Skip to content

Commit

Permalink
Update functions taking Predicate[T] to accept `Optional[Predicate[…
Browse files Browse the repository at this point in the history
…T]]`.
  • Loading branch information
nekitdev committed Oct 11, 2022
1 parent 48689bb commit aea7b30
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 107 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

<!-- changelogging: start -->

## 0.5.0 (2022-10-11)

### Changes

- Functions taking `Predicate[T]` have been updated to accept `Optional[Predicate[T]]`.
Passing `None` as an argument is identical to passing `bool`.

There are three functions which do not accept `None`, though:
- `drop_while`
- `skip_while`
- `take_while`

This choice is motivated by the fact that it does not make much sense to `do_while(None)`.

## 0.4.0 (2022-10-08)

### Changes
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Or by directly specifying it in the configuration like so:

```toml
[tool.poetry.dependencies]
iters = "^0.4.0"
iters = "^0.5.0"
```

Alternatively, you can add it directly from the source:
Expand Down
2 changes: 1 addition & 1 deletion iters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
__title__ = "iters"
__author__ = "nekitdev"
__license__ = "MIT"
__version__ = "0.4.0"
__version__ = "0.5.0"

from iters.async_iters import (
AsyncIter,
Expand Down
50 changes: 26 additions & 24 deletions iters/async_iters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ async def all_unique_fast_by(self, key: Unary[T, Q]) -> bool:
async def all_unique_fast_by_await(self, key: AsyncUnary[T, Q]) -> bool:
return await async_all_unique_fast_await(self.iterator, key)

def remove(self, predicate: Predicate[T]) -> AsyncIter[T]:
def remove(self, predicate: Optional[Predicate[T]]) -> AsyncIter[T]:
return self.create(async_remove(predicate, self.iterator))

def remove_await(self, predicate: AsyncPredicate[T]) -> AsyncIter[T]:
Expand All @@ -1288,13 +1288,13 @@ def remove_duplicates_by(self, key: Unary[T, U]) -> AsyncIter[T]:
def remove_duplicates_by_await(self, key: AsyncUnary[T, U]) -> AsyncIter[T]:
return self.create(async_remove_duplicates_await(self.iterator, key))

def filter(self, predicate: Predicate[T]) -> AsyncIter[T]:
def filter(self, predicate: Optional[Predicate[T]]) -> AsyncIter[T]:
return self.create(async_filter(predicate, self.iterator))

def filter_await(self, predicate: AsyncPredicate[T]) -> AsyncIter[T]:
return self.create(async_filter_await(predicate, self.iterator))

def filter_false(self, predicate: Predicate[T]) -> AsyncIter[T]:
def filter_false(self, predicate: Optional[Predicate[T]]) -> AsyncIter[T]:
return self.create(async_filter_false(predicate, self.iterator))

def filter_false_await(self, predicate: AsyncPredicate[T]) -> AsyncIter[T]:
Expand All @@ -1311,19 +1311,19 @@ def filter_except_await(
def compress(self, selectors: AnySelectors) -> AsyncIter[T]:
return self.create(async_compress(self.iterator, selectors))

def position_all(self, predicate: Predicate[T]) -> AsyncIter[int]:
def position_all(self, predicate: Optional[Predicate[T]]) -> AsyncIter[int]:
return self.create(async_position_all(predicate, self.iterator))

def position_all_await(self, predicate: AsyncPredicate[T]) -> AsyncIter[int]:
return self.create(async_position_all_await(predicate, self.iterator))

async def position(self, predicate: Predicate[T]) -> int:
async def position(self, predicate: Optional[Predicate[T]]) -> int:
return await async_position(predicate, self.iterator)

async def position_or(self, predicate: Predicate[T], default: V) -> Union[int, V]:
async def position_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[int, V]:
return await async_position(predicate, self.iterator, default)

async def position_or_none(self, predicate: Predicate[T]) -> Optional[int]:
async def position_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[int]:
return await self.position_or(predicate, None)

async def position_await(self, predicate: AsyncPredicate[T]) -> int:
Expand All @@ -1335,19 +1335,19 @@ async def position_await_or(self, predicate: AsyncPredicate[T], default: V) -> U
async def position_await_or_none(self, predicate: AsyncPredicate[T]) -> Optional[int]:
return await self.position_await_or(predicate, None)

def find_all(self, predicate: Predicate[T]) -> AsyncIter[T]:
def find_all(self, predicate: Optional[Predicate[T]]) -> AsyncIter[T]:
return self.create(async_find_all(predicate, self.iterator))

def find_all_await(self, predicate: AsyncPredicate[T]) -> AsyncIter[T]:
return self.create(async_find_all_await(predicate, self.iterator))

async def find(self, predicate: Predicate[T]) -> T:
async def find(self, predicate: Optional[Predicate[T]]) -> T:
return await async_find(predicate, self.iterator)

async def find_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
async def find_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return await async_find(predicate, self.iterator, default) # type: ignore # strange

async def find_or_none(self, predicate: Predicate[T]) -> Optional[T]:
async def find_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return await self.find_or(predicate, None)

async def find_await(self, predicate: AsyncPredicate[T]) -> T:
Expand All @@ -1359,13 +1359,13 @@ async def find_await_or(self, predicate: AsyncPredicate[T], default: V) -> Union
async def find_await_or_none(self, predicate: AsyncPredicate[T]) -> Optional[T]:
return await self.find_await_or(predicate, None)

async def find_or_first(self, predicate: Predicate[T]) -> T:
async def find_or_first(self, predicate: Optional[Predicate[T]]) -> T:
return await async_find_or_first(predicate, self.iterator)

async def find_or_first_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
async def find_or_first_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return await async_find_or_first(predicate, self.iterator, default) # type: ignore # strange

async def find_or_first_or_none(self, predicate: Predicate[T]) -> Optional[T]:
async def find_or_first_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return await self.find_or_first_or(predicate, None)

async def find_or_first_await(self, predicate: AsyncPredicate[T]) -> T:
Expand All @@ -1377,13 +1377,13 @@ async def find_or_first_await_or(self, predicate: AsyncPredicate[T], default: V)
async def find_or_first_await_or_none(self, predicate: AsyncPredicate[T]) -> Optional[T]:
return await self.find_or_first_await_or(predicate, None)

async def find_or_last(self, predicate: Predicate[T]) -> T:
async def find_or_last(self, predicate: Optional[Predicate[T]]) -> T:
return await async_find_or_last(predicate, self.iterator)

async def find_or_last_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
async def find_or_last_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return await async_find_or_last(predicate, self.iterator, default) # type: ignore # strange

async def find_or_last_or_none(self, predicate: Predicate[T]) -> Optional[T]:
async def find_or_last_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return await self.find_or_last_or(predicate, None)

async def find_or_last_await(self, predicate: AsyncPredicate[T]) -> T:
Expand Down Expand Up @@ -1555,21 +1555,21 @@ def flat_map(self, function: Unary[T, AnyIterable[U]]) -> AsyncIter[U]:
def flat_map_await(self, function: AsyncUnary[T, AnyIterable[U]]) -> AsyncIter[U]:
return self.create(async_flat_map_await(function, self.iterator))

def filter_map(self, predicate: Predicate[T], function: Unary[T, U]) -> AsyncIter[U]:
def filter_map(self, predicate: Optional[Predicate[T]], function: Unary[T, U]) -> AsyncIter[U]:
return self.create(async_filter_map(predicate, function, self.iterator))

def filter_await_map(self, predicate: AsyncPredicate[T], function: Unary[T, U]) -> AsyncIter[U]:
return self.create(async_filter_await_map(predicate, function, self.iterator))

def filter_map_await(self, predicate: Predicate[T], function: AsyncUnary[T, U]) -> AsyncIter[U]:
def filter_map_await(self, predicate: Optional[Predicate[T]], function: AsyncUnary[T, U]) -> AsyncIter[U]:
return self.create(async_filter_map_await(predicate, function, self.iterator))

def filter_await_map_await(
self, predicate: AsyncPredicate[T], function: AsyncUnary[T, U]
) -> AsyncIter[U]:
return self.create(async_filter_await_map_await(predicate, function, self.iterator))

def filter_false_map(self, predicate: Predicate[T], function: Unary[T, U]) -> AsyncIter[U]:
def filter_false_map(self, predicate: Optional[Predicate[T]], function: Unary[T, U]) -> AsyncIter[U]:
return self.create(async_filter_false_map(predicate, function, self.iterator))

def filter_false_await_map(
Expand All @@ -1578,7 +1578,7 @@ def filter_false_await_map(
return self.create(async_filter_false_await_map(predicate, function, self.iterator))

def filter_false_map_await(
self, predicate: Predicate[T], function: AsyncUnary[T, U]
self, predicate: Optional[Predicate[T]], function: AsyncUnary[T, U]
) -> AsyncIter[U]:
return self.create(async_filter_false_map_await(predicate, function, self.iterator))

Expand Down Expand Up @@ -2784,7 +2784,7 @@ def unique_by(self, key: Unary[T, V]) -> AsyncIter[T]:
def unique_by_await(self, key: AsyncUnary[T, V]) -> AsyncIter[T]:
return self.create(async_unique_await(self.iterator, key))

def partition(self, predicate: Predicate[T]) -> Tuple[AsyncIter[T], AsyncIter[T]]:
def partition(self, predicate: Optional[Predicate[T]]) -> Tuple[AsyncIter[T], AsyncIter[T]]:
true, false = async_partition(predicate, self.iterator)

return (self.create(true), self.create(false))
Expand All @@ -2794,19 +2794,21 @@ def partition_await(self, predicate: AsyncPredicate[T]) -> Tuple[AsyncIter[T], A

return (self.create(true), self.create(false))

def partition_unsafe(self, predicate: Predicate[T]) -> Tuple[AsyncIter[T], AsyncIter[T]]:
def partition_unsafe(self, predicate: Optional[Predicate[T]]) -> Tuple[AsyncIter[T], AsyncIter[T]]:
true, false = async_partition_unsafe(predicate, self.iterator)

return (self.create(true), self.create(false))

partition_infinite = partition_unsafe

def partition_unsafe_await(
self, predicate: AsyncPredicate[T]
) -> Tuple[AsyncIter[T], AsyncIter[T]]:
true, false = async_partition_unsafe_await(predicate, self.iterator)

return (self.create(true), self.create(false))

partition_infinite = partition_unsafe
partition_infinite_await = partition_unsafe_await

def copy(self) -> AsyncIter[T]:
iterator, result = async_copy(self.iterator)
Expand Down
44 changes: 13 additions & 31 deletions iters/async_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2681,13 +2681,13 @@ async def async_find_await(


@overload
async def async_find_or_first(predicate: Predicate[T], iterable: AnyIterable[T]) -> T:
async def async_find_or_first(predicate: Optional[Predicate[T]], iterable: AnyIterable[T]) -> T:
... # pragma: overload


@overload
async def async_find_or_first(
predicate: Predicate[T], iterable: AnyIterable[T], default: U
predicate: Optional[Predicate[T]], iterable: AnyIterable[T], default: U
) -> Union[T, U]:
... # pragma: overload

Expand Down Expand Up @@ -4649,21 +4649,14 @@ async def async_cycle(iterable: AnyIterable[T]) -> AsyncIterator[T]:


async def async_drop_while(
predicate: Optional[Predicate[T]], iterable: AnyIterable[T]
predicate: Predicate[T], iterable: AnyIterable[T]
) -> AsyncIterator[T]:
iterator = async_iter(iterable)

if predicate is None:
async for item in iterator:
if not item:
yield item
break

else:
async for item in iterator:
if not predicate(item):
yield item
break
async for item in iterator:
if not predicate(item):
yield item
break

async for item in iterator:
yield item
Expand All @@ -4690,25 +4683,14 @@ async def async_drop_while_await(


async def async_take_while(
predicate: Optional[Predicate[T]], iterable: AnyIterable[T]
predicate: Predicate[T], iterable: AnyIterable[T]
) -> AsyncIterator[T]:
iterator = async_iter(iterable)

if predicate is None:
async for item in iterator:
if item:
yield item

else:
break

else:
async for item in iterator:
if predicate(item):
yield item
async for item in async_iter(iterable):
if predicate(item):
yield item

else:
break
else:
break


async def async_take_while_await(
Expand Down
38 changes: 19 additions & 19 deletions iters/iters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ def all_unique_fast(self: Iter[Q]) -> bool:
def all_unique_fast_by(self, key: Unary[T, Q]) -> bool:
return all_unique_fast(self.iterator, key)

def remove(self, predicate: Predicate[T]) -> Iter[T]:
def remove(self, predicate: Optional[Predicate[T]]) -> Iter[T]:
return self.create(remove(predicate, self.iterator))

def remove_duplicates(self) -> Iter[T]:
Expand All @@ -1173,10 +1173,10 @@ def remove_duplicates(self) -> Iter[T]:
def remove_duplicates_by(self, key: Unary[T, U]) -> Iter[T]:
return self.create(remove_duplicates(self.iterator, key))

def filter(self, predicate: Predicate[T]) -> Iter[T]:
def filter(self, predicate: Optional[Predicate[T]]) -> Iter[T]:
return self.create(filter(predicate, self.iterator))

def filter_false(self, predicate: Predicate[T]) -> Iter[T]:
def filter_false(self, predicate: Optional[Predicate[T]]) -> Iter[T]:
return self.create(filter_false(predicate, self.iterator))

def filter_except(self, validate: Unary[T, Any], *errors: AnyExceptionType) -> Iter[T]:
Expand All @@ -1185,46 +1185,46 @@ def filter_except(self, validate: Unary[T, Any], *errors: AnyExceptionType) -> I
def compress(self, selectors: Selectors) -> Iter[T]:
return self.create(compress(self.iterator, selectors))

def position_all(self, predicate: Predicate[T]) -> Iter[int]:
def position_all(self, predicate: Optional[Predicate[T]]) -> Iter[int]:
return self.create(position_all(predicate, self.iterator))

def position(self, predicate: Predicate[T]) -> int:
def position(self, predicate: Optional[Predicate[T]]) -> int:
return position(predicate, self.iterator)

def position_or(self, predicate: Predicate[T], default: V) -> Union[int, V]:
def position_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[int, V]:
return position(predicate, self.iterator, default)

def position_or_none(self, predicate: Predicate[T]) -> Optional[int]:
def position_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[int]:
return self.position_or(predicate, None)

def find_all(self, predicate: Predicate[T]) -> Iter[T]:
def find_all(self, predicate: Optional[Predicate[T]]) -> Iter[T]:
return self.create(find_all(predicate, self.iterator))

def find(self, predicate: Predicate[T]) -> T:
def find(self, predicate: Optional[Predicate[T]]) -> T:
return find(predicate, self.iterator)

def find_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
def find_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return find(predicate, self.iterator, default) # type: ignore # strange

def find_or_none(self, predicate: Predicate[T]) -> Optional[T]:
def find_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return self.find_or(predicate, None)

def find_or_first(self, predicate: Predicate[T]) -> T:
def find_or_first(self, predicate: Optional[Predicate[T]]) -> T:
return find_or_first(predicate, self.iterator)

def find_or_first_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
def find_or_first_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return find_or_first(predicate, self.iterator, default) # type: ignore # strange

def find_or_first_or_none(self, predicate: Predicate[T]) -> Optional[T]:
def find_or_first_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return self.find_or_first_or(predicate, None)

def find_or_last(self, predicate: Predicate[T]) -> T:
def find_or_last(self, predicate: Optional[Predicate[T]]) -> T:
return find_or_last(predicate, self.iterator)

def find_or_last_or(self, predicate: Predicate[T], default: V) -> Union[T, V]:
def find_or_last_or(self, predicate: Optional[Predicate[T]], default: V) -> Union[T, V]:
return find_or_last(predicate, self.iterator, default) # type: ignore # strange

def find_or_last_or_none(self, predicate: Predicate[T]) -> Optional[T]:
def find_or_last_or_none(self, predicate: Optional[Predicate[T]]) -> Optional[T]:
return self.find_or_last_or(predicate, None)

def contains(self, item: V) -> bool:
Expand Down Expand Up @@ -1328,10 +1328,10 @@ def map_except(self, function: Unary[T, U], *errors: AnyExceptionType) -> Iter[U
def flat_map(self, function: Unary[T, Iterable[U]]) -> Iter[U]:
return self.create(flat_map(function, self.iterator))

def filter_map(self, predicate: Predicate[T], function: Unary[T, U]) -> Iter[U]:
def filter_map(self, predicate: Optional[Predicate[T]], function: Unary[T, U]) -> Iter[U]:
return self.create(filter_map(predicate, function, self.iterator))

def filter_false_map(self, predicate: Predicate[T], function: Unary[T, U]) -> Iter[U]:
def filter_false_map(self, predicate: Optional[Predicate[T]], function: Unary[T, U]) -> Iter[U]:
return self.create(filter_false_map(predicate, function, self.iterator))

def flatten(self: Iter[Iterable[U]]) -> Iter[U]:
Expand Down
Loading

0 comments on commit aea7b30

Please sign in to comment.