reactivex 4.1.0__py3-none-any.whl → 5.0.0a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. reactivex/__init__.py +35 -39
  2. reactivex/_version.py +1 -1
  3. reactivex/abc/disposable.py +3 -4
  4. reactivex/abc/observable.py +13 -6
  5. reactivex/abc/observer.py +2 -1
  6. reactivex/abc/periodicscheduler.py +7 -6
  7. reactivex/abc/scheduler.py +10 -9
  8. reactivex/abc/subject.py +5 -5
  9. reactivex/disposable/compositedisposable.py +4 -4
  10. reactivex/disposable/disposable.py +1 -2
  11. reactivex/disposable/multipleassignmentdisposable.py +2 -3
  12. reactivex/disposable/refcountdisposable.py +1 -2
  13. reactivex/disposable/serialdisposable.py +4 -5
  14. reactivex/disposable/singleassignmentdisposable.py +3 -4
  15. reactivex/internal/__init__.py +2 -0
  16. reactivex/internal/basic.py +2 -2
  17. reactivex/internal/concurrency.py +2 -1
  18. reactivex/internal/curry.py +59 -0
  19. reactivex/internal/exceptions.py +7 -12
  20. reactivex/internal/priorityqueue.py +2 -2
  21. reactivex/internal/utils.py +3 -2
  22. reactivex/notification.py +22 -21
  23. reactivex/observable/case.py +5 -6
  24. reactivex/observable/catch.py +3 -2
  25. reactivex/observable/combinelatest.py +4 -5
  26. reactivex/observable/concat.py +3 -2
  27. reactivex/observable/connectableobservable.py +7 -7
  28. reactivex/observable/defer.py +4 -3
  29. reactivex/observable/empty.py +3 -4
  30. reactivex/observable/forkjoin.py +5 -5
  31. reactivex/observable/fromcallback.py +4 -3
  32. reactivex/observable/fromfuture.py +2 -2
  33. reactivex/observable/fromiterable.py +4 -3
  34. reactivex/observable/generate.py +2 -2
  35. reactivex/observable/generatewithrelativetime.py +4 -3
  36. reactivex/observable/groupedobservable.py +4 -4
  37. reactivex/observable/ifthen.py +3 -2
  38. reactivex/observable/interval.py +1 -4
  39. reactivex/observable/marbles.py +18 -17
  40. reactivex/observable/mixins/__init__.py +32 -0
  41. reactivex/observable/mixins/combination.py +481 -0
  42. reactivex/observable/mixins/conditional.py +135 -0
  43. reactivex/observable/mixins/error_handling.py +130 -0
  44. reactivex/observable/mixins/filtering.py +1119 -0
  45. reactivex/observable/mixins/mathematical.py +277 -0
  46. reactivex/observable/mixins/multicasting.py +306 -0
  47. reactivex/observable/mixins/testing.py +193 -0
  48. reactivex/observable/mixins/time_based.py +209 -0
  49. reactivex/observable/mixins/transformation.py +632 -0
  50. reactivex/observable/mixins/utility.py +811 -0
  51. reactivex/observable/mixins/windowing.py +688 -0
  52. reactivex/observable/never.py +2 -2
  53. reactivex/observable/observable.py +72 -25
  54. reactivex/observable/onerrorresumenext.py +7 -6
  55. reactivex/observable/range.py +6 -6
  56. reactivex/observable/repeat.py +2 -2
  57. reactivex/observable/returnvalue.py +6 -5
  58. reactivex/observable/start.py +3 -2
  59. reactivex/observable/startasync.py +2 -1
  60. reactivex/observable/throw.py +3 -3
  61. reactivex/observable/timer.py +12 -12
  62. reactivex/observable/toasync.py +3 -2
  63. reactivex/observable/using.py +5 -4
  64. reactivex/observable/withlatestfrom.py +4 -5
  65. reactivex/observable/zip.py +7 -6
  66. reactivex/observer/autodetachobserver.py +4 -4
  67. reactivex/observer/observer.py +5 -4
  68. reactivex/observer/scheduledobserver.py +2 -2
  69. reactivex/operators/__init__.py +162 -208
  70. reactivex/operators/_all.py +23 -6
  71. reactivex/operators/_amb.py +88 -75
  72. reactivex/operators/_asobservable.py +20 -17
  73. reactivex/operators/_average.py +48 -45
  74. reactivex/operators/_buffer.py +81 -35
  75. reactivex/operators/_bufferwithtime.py +29 -9
  76. reactivex/operators/_bufferwithtimeorcount.py +27 -8
  77. reactivex/operators/_catch.py +33 -32
  78. reactivex/operators/_combinelatest.py +28 -20
  79. reactivex/operators/_concat.py +16 -13
  80. reactivex/operators/_contains.py +25 -6
  81. reactivex/operators/_count.py +24 -8
  82. reactivex/operators/_debounce.py +141 -138
  83. reactivex/operators/_defaultifempty.py +45 -42
  84. reactivex/operators/_delay.py +24 -23
  85. reactivex/operators/_delaysubscription.py +23 -21
  86. reactivex/operators/_delaywithmapper.py +10 -11
  87. reactivex/operators/_dematerialize.py +25 -21
  88. reactivex/operators/_distinct.py +50 -46
  89. reactivex/operators/_distinctuntilchanged.py +60 -57
  90. reactivex/operators/_do.py +123 -116
  91. reactivex/operators/_dowhile.py +3 -2
  92. reactivex/operators/_elementatordefault.py +57 -33
  93. reactivex/operators/_exclusive.py +59 -53
  94. reactivex/operators/_expand.py +82 -77
  95. reactivex/operators/_filter.py +63 -68
  96. reactivex/operators/_finallyaction.py +3 -2
  97. reactivex/operators/_find.py +49 -32
  98. reactivex/operators/_first.py +18 -11
  99. reactivex/operators/_firstordefault.py +5 -4
  100. reactivex/operators/_flatmap.py +89 -83
  101. reactivex/operators/_forkjoin.py +23 -18
  102. reactivex/operators/_groupby.py +27 -6
  103. reactivex/operators/_groupbyuntil.py +8 -5
  104. reactivex/operators/_groupjoin.py +7 -6
  105. reactivex/operators/_ignoreelements.py +20 -15
  106. reactivex/operators/_isempty.py +15 -4
  107. reactivex/operators/_join.py +6 -5
  108. reactivex/operators/_last.py +36 -31
  109. reactivex/operators/_lastordefault.py +8 -8
  110. reactivex/operators/_map.py +54 -39
  111. reactivex/operators/_materialize.py +30 -31
  112. reactivex/operators/_max.py +18 -11
  113. reactivex/operators/_maxby.py +5 -5
  114. reactivex/operators/_merge.py +132 -129
  115. reactivex/operators/_min.py +16 -10
  116. reactivex/operators/_minby.py +9 -8
  117. reactivex/operators/_multicast.py +9 -9
  118. reactivex/operators/_observeon.py +35 -31
  119. reactivex/operators/_onerrorresumenext.py +2 -1
  120. reactivex/operators/_pairwise.py +38 -34
  121. reactivex/operators/_partition.py +80 -73
  122. reactivex/operators/_pluck.py +4 -3
  123. reactivex/operators/_publish.py +36 -21
  124. reactivex/operators/_publishvalue.py +8 -7
  125. reactivex/operators/_reduce.py +16 -12
  126. reactivex/operators/_repeat.py +33 -30
  127. reactivex/operators/_replay.py +9 -9
  128. reactivex/operators/_retry.py +12 -10
  129. reactivex/operators/_sample.py +31 -27
  130. reactivex/operators/_scan.py +41 -39
  131. reactivex/operators/_sequenceequal.py +8 -7
  132. reactivex/operators/_single.py +20 -13
  133. reactivex/operators/_singleordefault.py +6 -5
  134. reactivex/operators/_skip.py +35 -32
  135. reactivex/operators/_skiplast.py +38 -34
  136. reactivex/operators/_skiplastwithtime.py +5 -4
  137. reactivex/operators/_skipuntil.py +40 -35
  138. reactivex/operators/_skipuntilwithtime.py +4 -3
  139. reactivex/operators/_skipwhile.py +65 -44
  140. reactivex/operators/_skipwithtime.py +50 -46
  141. reactivex/operators/_slice.py +58 -53
  142. reactivex/operators/_some.py +48 -47
  143. reactivex/operators/_startswith.py +17 -15
  144. reactivex/operators/_subscribeon.py +44 -41
  145. reactivex/operators/_sum.py +23 -6
  146. reactivex/operators/_switchlatest.py +71 -69
  147. reactivex/operators/_take.py +37 -33
  148. reactivex/operators/_takelast.py +37 -36
  149. reactivex/operators/_takelastbuffer.py +38 -37
  150. reactivex/operators/_takelastwithtime.py +60 -56
  151. reactivex/operators/_takeuntil.py +33 -32
  152. reactivex/operators/_takeuntilwithtime.py +42 -39
  153. reactivex/operators/_takewhile.py +108 -100
  154. reactivex/operators/_takewithtime.py +46 -41
  155. reactivex/operators/_throttlefirst.py +52 -45
  156. reactivex/operators/_timeinterval.py +40 -36
  157. reactivex/operators/_timeout.py +81 -79
  158. reactivex/operators/_timeoutwithmapper.py +6 -5
  159. reactivex/operators/_timestamp.py +24 -22
  160. reactivex/operators/_todict.py +51 -43
  161. reactivex/operators/_tofuture.py +24 -15
  162. reactivex/operators/_toiterable.py +33 -27
  163. reactivex/operators/_tomarbles.py +5 -5
  164. reactivex/operators/_toset.py +29 -19
  165. reactivex/operators/_whiledo.py +2 -1
  166. reactivex/operators/_window.py +100 -99
  167. reactivex/operators/_windowwithcount.py +56 -54
  168. reactivex/operators/_windowwithtime.py +95 -79
  169. reactivex/operators/_windowwithtimeorcount.py +85 -69
  170. reactivex/operators/_withlatestfrom.py +13 -9
  171. reactivex/operators/_zip.py +67 -63
  172. reactivex/operators/connectable/_refcount.py +4 -3
  173. reactivex/pipe.py +2 -1
  174. reactivex/run.py +8 -4
  175. reactivex/scheduler/catchscheduler.py +11 -10
  176. reactivex/scheduler/currentthreadscheduler.py +2 -3
  177. reactivex/scheduler/eventloop/asyncioscheduler.py +7 -6
  178. reactivex/scheduler/eventloop/asynciothreadsafescheduler.py +12 -14
  179. reactivex/scheduler/eventloop/eventletscheduler.py +4 -4
  180. reactivex/scheduler/eventloop/geventscheduler.py +4 -4
  181. reactivex/scheduler/eventloop/ioloopscheduler.py +4 -4
  182. reactivex/scheduler/eventloop/twistedscheduler.py +4 -4
  183. reactivex/scheduler/eventloopscheduler.py +9 -12
  184. reactivex/scheduler/historicalscheduler.py +1 -2
  185. reactivex/scheduler/immediatescheduler.py +5 -4
  186. reactivex/scheduler/mainloop/gtkscheduler.py +6 -7
  187. reactivex/scheduler/mainloop/pygamescheduler.py +4 -4
  188. reactivex/scheduler/mainloop/qtscheduler.py +6 -6
  189. reactivex/scheduler/mainloop/tkinterscheduler.py +4 -4
  190. reactivex/scheduler/mainloop/wxscheduler.py +7 -7
  191. reactivex/scheduler/newthreadscheduler.py +6 -8
  192. reactivex/scheduler/periodicscheduler.py +4 -4
  193. reactivex/scheduler/scheduleditem.py +4 -4
  194. reactivex/scheduler/scheduler.py +5 -5
  195. reactivex/scheduler/threadpoolscheduler.py +3 -3
  196. reactivex/scheduler/timeoutscheduler.py +5 -4
  197. reactivex/scheduler/trampoline.py +1 -2
  198. reactivex/scheduler/trampolinescheduler.py +5 -6
  199. reactivex/scheduler/virtualtimescheduler.py +4 -4
  200. reactivex/subject/asyncsubject.py +2 -2
  201. reactivex/subject/behaviorsubject.py +2 -2
  202. reactivex/subject/innersubscription.py +2 -2
  203. reactivex/subject/replaysubject.py +8 -8
  204. reactivex/subject/subject.py +4 -4
  205. reactivex/testing/coldobservable.py +5 -5
  206. reactivex/testing/hotobservable.py +6 -6
  207. reactivex/testing/marbles.py +21 -20
  208. reactivex/testing/mockdisposable.py +1 -3
  209. reactivex/testing/mockobserver.py +2 -2
  210. reactivex/testing/reactivetest.py +2 -2
  211. reactivex/testing/recorded.py +1 -1
  212. reactivex/testing/subscription.py +3 -3
  213. reactivex/testing/testscheduler.py +13 -12
  214. reactivex/typing.py +25 -14
  215. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/METADATA +59 -26
  216. reactivex-5.0.0a2.dist-info/RECORD +236 -0
  217. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/WHEEL +1 -1
  218. reactivex-4.1.0.dist-info/RECORD +0 -223
  219. {reactivex-4.1.0.dist-info → reactivex-5.0.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -1,83 +1,87 @@
1
- from typing import Any, Callable, Iterable, Optional, Tuple, TypeVar
1
+ from collections.abc import Iterable
2
+ from typing import Any, TypeVar
2
3
 
3
4
  import reactivex
4
5
  from reactivex import Observable, abc
6
+ from reactivex.internal import curry_flip
5
7
 
6
8
  _T = TypeVar("_T")
7
9
  _TOther = TypeVar("_TOther")
8
10
 
9
11
 
12
+ @curry_flip
10
13
  def zip_(
14
+ source: Observable[Any],
11
15
  *args: Observable[Any],
12
- ) -> Callable[[Observable[Any]], Observable[Tuple[Any, ...]]]:
13
- def _zip(source: Observable[Any]) -> Observable[Tuple[Any, ...]]:
14
- """Merges the specified observable sequences into one observable
15
- sequence by creating a tuple whenever all of the
16
- observable sequences have produced an element at a corresponding
17
- index.
16
+ ) -> Observable[tuple[Any, ...]]:
17
+ """Merges the specified observable sequences into one observable
18
+ sequence by creating a tuple whenever all of the
19
+ observable sequences have produced an element at a corresponding
20
+ index.
18
21
 
19
- Example:
20
- >>> res = zip(source)
22
+ Example:
23
+ >>> res = source.pipe(zip(obs1, obs2))
24
+ >>> res = zip(obs1, obs2)(source)
21
25
 
22
- Args:
23
- source: Source observable to zip.
26
+ Args:
27
+ source: Source observable to zip.
28
+ *args: Additional observables to zip with.
24
29
 
25
- Returns:
26
- An observable sequence containing the result of combining
27
- elements of the sources as a tuple.
28
- """
29
- return reactivex.zip(source, *args)
30
-
31
- return _zip
30
+ Returns:
31
+ An observable sequence containing the result of combining
32
+ elements of the sources as a tuple.
33
+ """
34
+ return reactivex.zip(source, *args)
32
35
 
33
36
 
37
+ @curry_flip
34
38
  def zip_with_iterable_(
39
+ source: Observable[_T],
35
40
  seq: Iterable[_TOther],
36
- ) -> Callable[[Observable[_T]], Observable[Tuple[_T, _TOther]]]:
37
- def zip_with_iterable(source: Observable[_T]) -> Observable[Tuple[_T, _TOther]]:
38
- """Merges the specified observable sequence and list into one
39
- observable sequence by creating a tuple whenever all of
40
- the observable sequences have produced an element at a
41
- corresponding index.
42
-
43
- Example
44
- >>> res = zip(source)
45
-
46
- Args:
47
- source: Source observable to zip.
48
-
49
- Returns:
50
- An observable sequence containing the result of combining
51
- elements of the sources as a tuple.
52
- """
53
-
54
- first = source
55
- second = iter(seq)
56
-
57
- def subscribe(
58
- observer: abc.ObserverBase[Tuple[_T, _TOther]],
59
- scheduler: Optional[abc.SchedulerBase] = None,
60
- ):
61
- index = 0
62
-
63
- def on_next(left: _T) -> None:
64
- nonlocal index
65
-
66
- try:
67
- right = next(second)
68
- except StopIteration:
69
- observer.on_completed()
70
- else:
71
- result = (left, right)
72
- observer.on_next(result)
73
-
74
- return first.subscribe(
75
- on_next, observer.on_error, observer.on_completed, scheduler=scheduler
76
- )
77
-
78
- return Observable(subscribe)
79
-
80
- return zip_with_iterable
41
+ ) -> Observable[tuple[_T, _TOther]]:
42
+ """Merges the specified observable sequence and list into one
43
+ observable sequence by creating a tuple whenever all of
44
+ the observable sequences have produced an element at a
45
+ corresponding index.
46
+
47
+ Example
48
+ >>> res = source.pipe(zip_with_iterable([1, 2, 3]))
49
+ >>> res = zip_with_iterable([1, 2, 3])(source)
50
+
51
+ Args:
52
+ source: Source observable to zip.
53
+ seq: Iterable sequence to zip with.
54
+
55
+ Returns:
56
+ An observable sequence containing the result of combining
57
+ elements of the sources as a tuple.
58
+ """
59
+
60
+ first = source
61
+ second = iter(seq)
62
+
63
+ def subscribe(
64
+ observer: abc.ObserverBase[tuple[_T, _TOther]],
65
+ scheduler: abc.SchedulerBase | None = None,
66
+ ):
67
+ index = 0
68
+
69
+ def on_next(left: _T) -> None:
70
+ nonlocal index
71
+
72
+ try:
73
+ right = next(second)
74
+ except StopIteration:
75
+ observer.on_completed()
76
+ else:
77
+ result = (left, right)
78
+ observer.on_next(result)
79
+
80
+ return first.subscribe(
81
+ on_next, observer.on_error, observer.on_completed, scheduler=scheduler
82
+ )
83
+
84
+ return Observable(subscribe)
81
85
 
82
86
 
83
87
  __all__ = ["zip_", "zip_with_iterable_"]
@@ -1,4 +1,5 @@
1
- from typing import Callable, Optional, TypeVar
1
+ from collections.abc import Callable
2
+ from typing import TypeVar
2
3
 
3
4
  from reactivex import ConnectableObservable, Observable, abc
4
5
  from reactivex.disposable import Disposable
@@ -12,13 +13,13 @@ def ref_count_() -> Callable[[ConnectableObservable[_T]], Observable[_T]]:
12
13
  observable sequence.
13
14
  """
14
15
 
15
- connectable_subscription: Optional[abc.DisposableBase] = None
16
+ connectable_subscription: abc.DisposableBase | None = None
16
17
  count = 0
17
18
 
18
19
  def ref_count(source: ConnectableObservable[_T]) -> Observable[_T]:
19
20
  def subscribe(
20
21
  observer: abc.ObserverBase[_T],
21
- scheduler: Optional[abc.SchedulerBase] = None,
22
+ scheduler: abc.SchedulerBase | None = None,
22
23
  ) -> abc.DisposableBase:
23
24
  nonlocal connectable_subscription, count
24
25
 
reactivex/pipe.py CHANGED
@@ -1,5 +1,6 @@
1
+ from collections.abc import Callable
1
2
  from functools import reduce
2
- from typing import Any, Callable, TypeVar, overload
3
+ from typing import Any, TypeVar, overload
3
4
 
4
5
  _A = TypeVar("_A")
5
6
  _B = TypeVar("_B")
reactivex/run.py CHANGED
@@ -1,17 +1,18 @@
1
1
  import threading
2
- from typing import Optional, TypeVar, cast
2
+ from typing import TypeVar, cast
3
3
 
4
+ from reactivex import abc
4
5
  from reactivex.internal.exceptions import SequenceContainsNoElementsError
5
6
  from reactivex.scheduler import NewThreadScheduler
6
7
 
7
8
  from .observable import Observable
8
9
 
9
- scheduler = NewThreadScheduler()
10
+ _default_scheduler = NewThreadScheduler()
10
11
 
11
12
  _T = TypeVar("_T")
12
13
 
13
14
 
14
- def run(source: Observable[_T]) -> _T:
15
+ def run(source: Observable[_T], scheduler: abc.SchedulerBase | None = None) -> _T:
15
16
  """Run source synchronously.
16
17
 
17
18
  Subscribes to the observable source. Then blocks and waits for the
@@ -23,6 +24,8 @@ def run(source: Observable[_T]) -> _T:
23
24
 
24
25
  Args:
25
26
  source: Observable source to run.
27
+ scheduler: Optional scheduler to use for subscription. If not
28
+ specified, defaults to a NewThreadScheduler.
26
29
 
27
30
  Raises:
28
31
  SequenceContainsNoElementsError: if observable completes
@@ -32,7 +35,8 @@ def run(source: Observable[_T]) -> _T:
32
35
  Returns:
33
36
  The last element emitted from the observable.
34
37
  """
35
- exception: Optional[Exception] = None
38
+ scheduler = scheduler or _default_scheduler
39
+ exception: Exception | None = None
36
40
  latch = threading.Event()
37
41
  has_result = False
38
42
  result: _T = cast(_T, None)
@@ -1,5 +1,6 @@
1
+ from collections.abc import Callable
1
2
  from datetime import datetime
2
- from typing import Callable, Optional, TypeVar, cast
3
+ from typing import TypeVar, cast
3
4
 
4
5
  from reactivex import abc, typing
5
6
  from reactivex.abc.scheduler import SchedulerBase
@@ -28,8 +29,8 @@ class CatchScheduler(PeriodicScheduler):
28
29
  super().__init__()
29
30
  self._scheduler: abc.SchedulerBase = scheduler
30
31
  self._handler: Callable[[Exception], bool] = handler
31
- self._recursive_original: Optional[abc.SchedulerBase] = None
32
- self._recursive_wrapper: Optional["CatchScheduler"] = None
32
+ self._recursive_original: abc.SchedulerBase | None = None
33
+ self._recursive_wrapper: CatchScheduler | None = None
33
34
 
34
35
  @property
35
36
  def now(self) -> datetime:
@@ -44,7 +45,7 @@ class CatchScheduler(PeriodicScheduler):
44
45
  return self._scheduler.now
45
46
 
46
47
  def schedule(
47
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
48
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
48
49
  ) -> abc.DisposableBase:
49
50
  """Schedules an action to be executed.
50
51
 
@@ -64,7 +65,7 @@ class CatchScheduler(PeriodicScheduler):
64
65
  self,
65
66
  duetime: typing.RelativeTime,
66
67
  action: typing.ScheduledAction[_TState],
67
- state: Optional[_TState] = None,
68
+ state: _TState | None = None,
68
69
  ) -> abc.DisposableBase:
69
70
  """Schedules an action to be executed after duetime.
70
71
 
@@ -85,7 +86,7 @@ class CatchScheduler(PeriodicScheduler):
85
86
  self,
86
87
  duetime: typing.AbsoluteTime,
87
88
  action: typing.ScheduledAction[_TState],
88
- state: Optional[_TState] = None,
89
+ state: _TState | None = None,
89
90
  ) -> abc.DisposableBase:
90
91
  """Schedules an action to be executed at duetime.
91
92
 
@@ -106,7 +107,7 @@ class CatchScheduler(PeriodicScheduler):
106
107
  self,
107
108
  period: typing.RelativeTime,
108
109
  action: typing.ScheduledPeriodicAction[_TState],
109
- state: Optional[_TState] = None,
110
+ state: _TState | None = None,
110
111
  ) -> abc.DisposableBase:
111
112
  """Schedules a periodic piece of work.
112
113
 
@@ -129,7 +130,7 @@ class CatchScheduler(PeriodicScheduler):
129
130
  disp: SingleAssignmentDisposable = SingleAssignmentDisposable()
130
131
  failed: bool = False
131
132
 
132
- def periodic(state: Optional[_TState] = None) -> Optional[_TState]:
133
+ def periodic(state: _TState | None = None) -> _TState | None:
133
134
  nonlocal failed
134
135
  if failed:
135
136
  return None
@@ -155,8 +156,8 @@ class CatchScheduler(PeriodicScheduler):
155
156
  parent = self
156
157
 
157
158
  def wrapped_action(
158
- self: abc.SchedulerBase, state: Optional[_TState]
159
- ) -> Optional[abc.DisposableBase]:
159
+ self: abc.SchedulerBase, state: _TState | None
160
+ ) -> abc.DisposableBase | None:
160
161
  try:
161
162
  return action(parent._get_recursive_wrapper(self), state)
162
163
  except Exception as ex:
@@ -1,6 +1,6 @@
1
1
  import logging
2
+ from collections.abc import MutableMapping
2
3
  from threading import Thread, current_thread, local
3
- from typing import MutableMapping
4
4
  from weakref import WeakKeyDictionary
5
5
 
6
6
  from .trampoline import Trampoline
@@ -37,7 +37,7 @@ class CurrentThreadScheduler(TrampolineScheduler):
37
37
  thread = current_thread()
38
38
  class_map = CurrentThreadScheduler._global.get(cls)
39
39
  if class_map is None:
40
- class_map_: MutableMapping[Thread, "CurrentThreadScheduler"] = (
40
+ class_map_: MutableMapping[Thread, CurrentThreadScheduler] = (
41
41
  WeakKeyDictionary()
42
42
  )
43
43
  CurrentThreadScheduler._global[cls] = class_map_
@@ -70,7 +70,6 @@ class _Local(local):
70
70
 
71
71
 
72
72
  class CurrentThreadSchedulerSingleton(CurrentThreadScheduler):
73
-
74
73
  _local = _Local()
75
74
 
76
75
  # pylint: disable=super-init-not-called
@@ -1,7 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  from datetime import datetime
4
- from typing import Optional, TypeVar
4
+ from typing import TypeVar
5
5
 
6
6
  from reactivex import abc, typing
7
7
  from reactivex.disposable import (
@@ -9,6 +9,7 @@ from reactivex.disposable import (
9
9
  Disposable,
10
10
  SingleAssignmentDisposable,
11
11
  )
12
+ from reactivex.internal.basic import default_now
12
13
 
13
14
  from ..periodicscheduler import PeriodicScheduler
14
15
 
@@ -26,13 +27,13 @@ class AsyncIOScheduler(PeriodicScheduler):
26
27
 
27
28
  Args:
28
29
  loop: Instance of asyncio event loop to use; typically, you would
29
- get this by asyncio.get_event_loop()
30
+ get this by asyncio.get_running_loop()
30
31
  """
31
32
  super().__init__()
32
33
  self._loop: asyncio.AbstractEventLoop = loop
33
34
 
34
35
  def schedule(
35
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
36
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
36
37
  ) -> abc.DisposableBase:
37
38
  """Schedules an action to be executed.
38
39
 
@@ -60,7 +61,7 @@ class AsyncIOScheduler(PeriodicScheduler):
60
61
  self,
61
62
  duetime: typing.RelativeTime,
62
63
  action: typing.ScheduledAction[_TState],
63
- state: Optional[_TState] = None,
64
+ state: _TState | None = None,
64
65
  ) -> abc.DisposableBase:
65
66
  """Schedules an action to be executed after duetime.
66
67
 
@@ -93,7 +94,7 @@ class AsyncIOScheduler(PeriodicScheduler):
93
94
  self,
94
95
  duetime: typing.AbsoluteTime,
95
96
  action: typing.ScheduledAction[_TState],
96
- state: Optional[_TState] = None,
97
+ state: _TState | None = None,
97
98
  ) -> abc.DisposableBase:
98
99
  """Schedules an action to be executed at duetime.
99
100
 
@@ -120,4 +121,4 @@ class AsyncIOScheduler(PeriodicScheduler):
120
121
  The scheduler's current time, as a datetime instance.
121
122
  """
122
123
 
123
- return self.to_datetime(self._loop.time())
124
+ return default_now()
@@ -1,7 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  from concurrent.futures import Future
4
- from typing import List, Optional, TypeVar
4
+ from typing import TypeVar
5
5
 
6
6
  from reactivex import abc, typing
7
7
  from reactivex.disposable import (
@@ -23,7 +23,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
23
23
  """
24
24
 
25
25
  def schedule(
26
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
26
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
27
27
  ) -> abc.DisposableBase:
28
28
  """Schedules an action to be executed.
29
29
 
@@ -47,7 +47,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
47
47
  handle.cancel()
48
48
  return
49
49
 
50
- future: "Future[int]" = Future()
50
+ future: Future[int] = Future()
51
51
 
52
52
  def cancel_handle() -> None:
53
53
  handle.cancel()
@@ -62,7 +62,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
62
62
  self,
63
63
  duetime: typing.RelativeTime,
64
64
  action: typing.ScheduledAction[_TState],
65
- state: Optional[_TState] = None,
65
+ state: _TState | None = None,
66
66
  ) -> abc.DisposableBase:
67
67
  """Schedules an action to be executed after duetime.
68
68
 
@@ -86,7 +86,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
86
86
 
87
87
  # the operations on the list used here are atomic, so there is no
88
88
  # need to protect its access with a lock
89
- handle: List[asyncio.Handle] = []
89
+ handle: list[asyncio.Handle] = []
90
90
 
91
91
  def stage2() -> None:
92
92
  handle.append(self._loop.call_later(seconds, interval))
@@ -105,7 +105,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
105
105
  do_cancel_handles()
106
106
  return
107
107
 
108
- future: "Future[int]" = Future()
108
+ future: Future[int] = Future()
109
109
 
110
110
  def cancel_handle() -> None:
111
111
  do_cancel_handles()
@@ -120,7 +120,7 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
120
120
  self,
121
121
  duetime: typing.AbsoluteTime,
122
122
  action: typing.ScheduledAction[_TState],
123
- state: Optional[_TState] = None,
123
+ state: _TState | None = None,
124
124
  ) -> abc.DisposableBase:
125
125
  """Schedules an action to be executed at duetime.
126
126
 
@@ -145,13 +145,11 @@ class AsyncIOThreadSafeScheduler(AsyncIOScheduler):
145
145
  """
146
146
  if not self._loop.is_running():
147
147
  return True
148
- current_loop = None
148
+
149
149
  try:
150
- # In python 3.7 there asyncio.get_running_loop() is prefered.
151
- current_loop = asyncio.get_event_loop()
150
+ current_loop = asyncio.get_running_loop()
152
151
  except RuntimeError:
153
- # If there is no loop in current thread at all, and it is not main
154
- # thread, we get error like:
155
- # RuntimeError: There is no current event loop in thread 'Thread-1'
156
- pass
152
+ # If no running event loop is found, assume we're in a different thread
153
+ return True
154
+
157
155
  return self._loop == current_loop
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from datetime import datetime
3
- from typing import Any, Optional, TypeVar
3
+ from typing import Any, TypeVar
4
4
 
5
5
  from reactivex import abc, typing
6
6
  from reactivex.disposable import (
@@ -33,7 +33,7 @@ class EventletScheduler(PeriodicScheduler):
33
33
  self._eventlet = eventlet
34
34
 
35
35
  def schedule(
36
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
36
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
37
37
  ) -> abc.DisposableBase:
38
38
  """Schedules an action to be executed.
39
39
 
@@ -62,7 +62,7 @@ class EventletScheduler(PeriodicScheduler):
62
62
  self,
63
63
  duetime: typing.RelativeTime,
64
64
  action: typing.ScheduledAction[_TState],
65
- state: Optional[_TState] = None,
65
+ state: _TState | None = None,
66
66
  ) -> abc.DisposableBase:
67
67
  """Schedules an action to be executed after duetime.
68
68
 
@@ -96,7 +96,7 @@ class EventletScheduler(PeriodicScheduler):
96
96
  self,
97
97
  duetime: typing.AbsoluteTime,
98
98
  action: typing.ScheduledAction[_TState],
99
- state: Optional[_TState] = None,
99
+ state: _TState | None = None,
100
100
  ) -> abc.DisposableBase:
101
101
  """Schedules an action to be executed at duetime.
102
102
 
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from datetime import datetime
3
- from typing import Any, Optional, TypeVar
3
+ from typing import Any, TypeVar
4
4
 
5
5
  from reactivex import abc, typing
6
6
  from reactivex.disposable import (
@@ -33,7 +33,7 @@ class GEventScheduler(PeriodicScheduler):
33
33
  self._gevent = gevent
34
34
 
35
35
  def schedule(
36
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
36
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
37
37
  ) -> abc.DisposableBase:
38
38
  """Schedules an action to be executed.
39
39
 
@@ -62,7 +62,7 @@ class GEventScheduler(PeriodicScheduler):
62
62
  self,
63
63
  duetime: typing.RelativeTime,
64
64
  action: typing.ScheduledAction[_TState],
65
- state: Optional[_TState] = None,
65
+ state: _TState | None = None,
66
66
  ) -> abc.DisposableBase:
67
67
  """Schedules an action to be executed after duetime.
68
68
 
@@ -97,7 +97,7 @@ class GEventScheduler(PeriodicScheduler):
97
97
  self,
98
98
  duetime: typing.AbsoluteTime,
99
99
  action: typing.ScheduledAction[_TState],
100
- state: Optional[_TState] = None,
100
+ state: _TState | None = None,
101
101
  ) -> abc.DisposableBase:
102
102
  """Schedules an action to be executed at duetime.
103
103
 
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from datetime import datetime
3
- from typing import Any, Optional, TypeVar
3
+ from typing import Any, TypeVar
4
4
 
5
5
  from reactivex import abc, typing
6
6
  from reactivex.disposable import (
@@ -34,7 +34,7 @@ class IOLoopScheduler(PeriodicScheduler):
34
34
  self._loop = loop
35
35
 
36
36
  def schedule(
37
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
37
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
38
38
  ) -> abc.DisposableBase:
39
39
  """Schedules an action to be executed.
40
40
 
@@ -66,7 +66,7 @@ class IOLoopScheduler(PeriodicScheduler):
66
66
  self,
67
67
  duetime: typing.RelativeTime,
68
68
  action: typing.ScheduledAction[_TState],
69
- state: Optional[_TState] = None,
69
+ state: _TState | None = None,
70
70
  ) -> abc.DisposableBase:
71
71
  """Schedules an action to be executed after duetime.
72
72
 
@@ -102,7 +102,7 @@ class IOLoopScheduler(PeriodicScheduler):
102
102
  self,
103
103
  duetime: typing.AbsoluteTime,
104
104
  action: typing.ScheduledAction[_TState],
105
- state: Optional[_TState] = None,
105
+ state: _TState | None = None,
106
106
  ) -> abc.DisposableBase:
107
107
  """Schedules an action to be executed at duetime.
108
108
 
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from datetime import datetime
3
- from typing import Any, Optional, TypeVar
3
+ from typing import Any, TypeVar
4
4
 
5
5
  from reactivex import abc, typing
6
6
  from reactivex.disposable import (
@@ -30,7 +30,7 @@ class TwistedScheduler(PeriodicScheduler):
30
30
  self._reactor = reactor
31
31
 
32
32
  def schedule(
33
- self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None
33
+ self, action: typing.ScheduledAction[_TState], state: _TState | None = None
34
34
  ) -> abc.DisposableBase:
35
35
  """Schedules an action to be executed.
36
36
 
@@ -49,7 +49,7 @@ class TwistedScheduler(PeriodicScheduler):
49
49
  self,
50
50
  duetime: typing.RelativeTime,
51
51
  action: typing.ScheduledAction[_TState],
52
- state: Optional[_TState] = None,
52
+ state: _TState | None = None,
53
53
  ) -> abc.DisposableBase:
54
54
  """Schedules an action to be executed after duetime.
55
55
 
@@ -83,7 +83,7 @@ class TwistedScheduler(PeriodicScheduler):
83
83
  self,
84
84
  duetime: typing.AbsoluteTime,
85
85
  action: typing.ScheduledAction[_TState],
86
- state: Optional[_TState] = None,
86
+ state: _TState | None = None,
87
87
  ) -> abc.DisposableBase:
88
88
  """Schedules an action to be executed at duetime.
89
89