Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
176 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,52 @@ | ||
from typing import Callable, Optional, TypeVar | ||
from typing import Optional, TypeVar, cast | ||
|
||
from reactivex import Observable, abc, empty | ||
from reactivex.curry import curry_flip | ||
from reactivex.internal import ArgumentOutOfRangeException | ||
|
||
_T = TypeVar("_T") | ||
|
||
|
||
def take_(count: int) -> Callable[[Observable[_T]], Observable[_T]]: | ||
@curry_flip(1) | ||
def take_(source: Observable[_T], count: int) -> Observable[_T]: | ||
if count < 0: | ||
raise ArgumentOutOfRangeException() | ||
|
||
def take(source: Observable[_T]) -> Observable[_T]: | ||
"""Returns a specified number of contiguous elements from the start of | ||
an observable sequence. | ||
"""Returns a specified number of contiguous elements from the start of | ||
an observable sequence. | ||
>>> take(source) | ||
>>> take(source) | ||
Keyword arguments: | ||
count -- The number of elements to return. | ||
Keyword arguments: | ||
count -- The number of elements to return. | ||
Returns an observable sequence that contains the specified number of | ||
elements from the start of the input sequence. | ||
""" | ||
Returns an observable sequence that contains the specified number of | ||
elements from the start of the input sequence. | ||
""" | ||
|
||
if not count: | ||
return empty() | ||
if not count: | ||
return cast(Observable[_T], empty()) | ||
|
||
def subscribe( | ||
observer: abc.ObserverBase[_T], | ||
scheduler: Optional[abc.SchedulerBase] = None, | ||
): | ||
remaining = count | ||
def subscribe( | ||
observer: abc.ObserverBase[_T], | ||
scheduler: Optional[abc.SchedulerBase] = None, | ||
): | ||
remaining = count | ||
|
||
def on_next(value: _T) -> None: | ||
nonlocal remaining | ||
def on_next(value: _T) -> None: | ||
nonlocal remaining | ||
|
||
if remaining > 0: | ||
remaining -= 1 | ||
observer.on_next(value) | ||
if not remaining: | ||
observer.on_completed() | ||
if remaining > 0: | ||
remaining -= 1 | ||
observer.on_next(value) | ||
if not remaining: | ||
observer.on_completed() | ||
|
||
return source.subscribe( | ||
on_next, observer.on_error, observer.on_completed, scheduler=scheduler | ||
) | ||
return source.subscribe( | ||
on_next, observer.on_error, observer.on_completed, scheduler=scheduler | ||
) | ||
|
||
return Observable(subscribe) | ||
|
||
return take | ||
return Observable(subscribe) | ||
|
||
|
||
__all__ = ["take_"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,58 @@ | ||
from datetime import datetime | ||
from typing import Callable, Optional, TypeVar | ||
from typing import Optional, TypeVar | ||
|
||
from reactivex import Observable, abc, typing | ||
from reactivex.curry import curry_flip | ||
from reactivex.scheduler import TimeoutScheduler | ||
|
||
_T = TypeVar("_T") | ||
|
||
|
||
@curry_flip(1) | ||
def throttle_first_( | ||
window_duration: typing.RelativeTime, scheduler: Optional[abc.SchedulerBase] = None | ||
) -> Callable[[Observable[_T]], Observable[_T]]: | ||
def throttle_first(source: Observable[_T]) -> Observable[_T]: | ||
"""Returns an observable that emits only the first item emitted | ||
by the source Observable during sequential time windows of a | ||
specified duration. | ||
Args: | ||
source: Source observable to throttle. | ||
Returns: | ||
An Observable that performs the throttle operation. | ||
""" | ||
|
||
def subscribe( | ||
observer: abc.ObserverBase[_T], | ||
scheduler_: Optional[abc.SchedulerBase] = None, | ||
) -> abc.DisposableBase: | ||
_scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() | ||
|
||
duration = _scheduler.to_timedelta(window_duration or 0.0) | ||
if duration <= _scheduler.to_timedelta(0): | ||
raise ValueError("window_duration cannot be less or equal zero.") | ||
last_on_next: Optional[datetime] = None | ||
|
||
def on_next(x: _T) -> None: | ||
nonlocal last_on_next | ||
emit = False | ||
now = _scheduler.now | ||
|
||
with source.lock: | ||
if not last_on_next or now - last_on_next >= duration: | ||
last_on_next = now | ||
emit = True | ||
if emit: | ||
observer.on_next(x) | ||
|
||
return source.subscribe( | ||
on_next, observer.on_error, observer.on_completed, scheduler=_scheduler | ||
) | ||
|
||
return Observable(subscribe) | ||
|
||
return throttle_first | ||
source: Observable[_T], | ||
window_duration: typing.RelativeTime, | ||
scheduler: Optional[abc.SchedulerBase] = None, | ||
) -> Observable[_T]: | ||
"""Returns an observable that emits only the first item emitted | ||
by the source Observable during sequential time windows of a | ||
specified duration. | ||
Args: | ||
source: Source observable to throttle. | ||
Returns: | ||
An Observable that performs the throttle operation. | ||
""" | ||
|
||
def subscribe( | ||
observer: abc.ObserverBase[_T], | ||
scheduler_: Optional[abc.SchedulerBase] = None, | ||
) -> abc.DisposableBase: | ||
_scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() | ||
|
||
duration = _scheduler.to_timedelta(window_duration or 0.0) | ||
if duration <= _scheduler.to_timedelta(0): | ||
raise ValueError("window_duration cannot be less or equal zero.") | ||
last_on_next: Optional[datetime] = None | ||
|
||
def on_next(x: _T) -> None: | ||
nonlocal last_on_next | ||
emit = False | ||
now = _scheduler.now | ||
|
||
with source.lock: | ||
if not last_on_next or now - last_on_next >= duration: | ||
last_on_next = now | ||
emit = True | ||
if emit: | ||
observer.on_next(x) | ||
|
||
return source.subscribe( | ||
on_next, observer.on_error, observer.on_completed, scheduler=_scheduler | ||
) | ||
|
||
return Observable(subscribe) | ||
|
||
|
||
__all__ = ["throttle_first_"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.