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
@@ -0,0 +1,277 @@
1
+ """Mathematical operators mixin for Observable."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast, overload
6
+
7
+ from reactivex import typing
8
+
9
+ if TYPE_CHECKING:
10
+ from reactivex.observable import Observable
11
+
12
+ _T = TypeVar("_T", covariant=True)
13
+ _TKey = TypeVar("_TKey")
14
+
15
+
16
+ class MathematicalMixin(Generic[_T]):
17
+ """Mixin providing mathematical operators for Observable.
18
+
19
+ This mixin adds operators that perform mathematical operations on sequences,
20
+ including counting, summing, averaging, and finding minimum/maximum values.
21
+ """
22
+
23
+ def _as_observable(self) -> Observable[_T]:
24
+ """Cast mixin instance to Observable preserving type parameter.
25
+
26
+ This is safe because this mixin is only ever used as part of the Observable
27
+ class through multiple inheritance. At runtime, `self` in mixin methods will
28
+ always be an Observable[_T] instance. The type checker cannot infer this
29
+ because it analyzes mixins in isolation.
30
+
31
+ Returns:
32
+ The instance cast to Observable[_T] for type-safe method access.
33
+ """
34
+ return cast("Observable[_T]", self)
35
+
36
+ def count(self, predicate: typing.Predicate[_T] | None = None) -> Observable[int]:
37
+ """Count the number of elements, optionally satisfying a predicate.
38
+
39
+ Returns an observable sequence containing a value that represents how many
40
+ elements in the specified observable sequence satisfy a condition if provided,
41
+ else the count of items.
42
+
43
+ Examples:
44
+ Fluent style:
45
+ >>> result = source.count()
46
+ >>> result = source.count(lambda x: x > 5)
47
+
48
+ Equivalent pipe style:
49
+ >>> from reactivex import operators as ops
50
+ >>> result = source.pipe(ops.count())
51
+
52
+ Args:
53
+ predicate: Optional function to test each source element for a condition.
54
+
55
+ Returns:
56
+ An observable sequence containing a single element with the number
57
+ of elements in the source sequence that satisfy the condition.
58
+
59
+ See Also:
60
+ - :func:`count <reactivex.operators.count>`
61
+ - :meth:`reduce`
62
+ """
63
+ from reactivex import operators as ops
64
+
65
+ return self._as_observable().pipe(ops.count(predicate))
66
+
67
+ @overload
68
+ def sum(self) -> Observable[float]: ...
69
+
70
+ @overload
71
+ def sum(self, key_mapper: typing.Mapper[_T, float]) -> Observable[float]: ...
72
+
73
+ def sum(
74
+ self, key_mapper: typing.Mapper[Any, float] | None = None
75
+ ) -> Observable[float]:
76
+ """Compute the sum of the sequence.
77
+
78
+ Computes the sum of a sequence of values that are obtained by invoking an
79
+ optional transform function on each element of the input sequence, else if
80
+ not specified computes the sum on each item in the sequence.
81
+
82
+ Examples:
83
+ Fluent style:
84
+ >>> result = rx.of(1, 2, 3, 4, 5).sum()
85
+ >>> result = source.sum(lambda x: x.value)
86
+
87
+ Equivalent pipe style:
88
+ >>> from reactivex import operators as ops
89
+ >>> result = source.pipe(ops.sum())
90
+
91
+ Args:
92
+ key_mapper: Optional transform function to apply to each element.
93
+
94
+ Returns:
95
+ An observable sequence containing a single element with the sum
96
+ of the values in the source sequence.
97
+
98
+ See Also:
99
+ - :func:`sum <reactivex.operators.sum>`
100
+ - :meth:`average`
101
+ - :meth:`reduce`
102
+ """
103
+ from reactivex import operators as ops
104
+
105
+ if key_mapper is None:
106
+ # Call operator directly with cast when no key_mapper is provided.
107
+ # sum() expects Observable[float] but we have Observable[_T].
108
+ source: Observable[float] = cast("Observable[float]", self._as_observable())
109
+ return ops.sum()(source)
110
+ return self._as_observable().pipe(ops.sum(key_mapper))
111
+
112
+ def average(
113
+ self, key_mapper: typing.Mapper[Any, float] | None = None
114
+ ) -> Observable[float]:
115
+ """Compute the average of the sequence.
116
+
117
+ Computes the average of an observable sequence of values that are
118
+ in the sequence or obtained by invoking a transform function on
119
+ each element if present.
120
+
121
+ Examples:
122
+ Fluent style:
123
+ >>> result = rx.of(1, 2, 3, 4, 5).average()
124
+ >>> result = source.average(lambda x: x.value)
125
+
126
+ Equivalent pipe style:
127
+ >>> from reactivex import operators as ops
128
+ >>> result = source.pipe(ops.average())
129
+
130
+ Args:
131
+ key_mapper: Optional transform function to apply to each element.
132
+
133
+ Returns:
134
+ An observable sequence containing a single element with the average
135
+ of the sequence of values.
136
+
137
+ See Also:
138
+ - :func:`average <reactivex.operators.average>`
139
+ - :meth:`sum`
140
+ """
141
+ from reactivex import operators as ops
142
+
143
+ return self._as_observable().pipe(ops.average(key_mapper))
144
+
145
+ def min(self, comparer: typing.Comparer[_T] | None = None) -> Observable[_T]:
146
+ """Find the minimum element.
147
+
148
+ Returns the minimum element in an observable sequence according to the
149
+ optional comparer else a default greater than less than check.
150
+
151
+ Examples:
152
+ Fluent style:
153
+ >>> result = source.min()
154
+ >>> result = source.min(lambda x, y: x.value < y.value)
155
+
156
+ Equivalent pipe style:
157
+ >>> from reactivex import operators as ops
158
+ >>> result = source.pipe(ops.min())
159
+
160
+ Args:
161
+ comparer: Optional comparer function for comparing elements.
162
+
163
+ Returns:
164
+ An observable sequence containing a single element with the minimum
165
+ element in the source sequence.
166
+
167
+ See Also:
168
+ - :func:`min <reactivex.operators.min>`
169
+ - :meth:`max`
170
+ - :meth:`min_by`
171
+ """
172
+ from reactivex import operators as ops
173
+
174
+ return self._as_observable().pipe(ops.min(comparer))
175
+
176
+ def max(self, comparer: typing.Comparer[_T] | None = None) -> Observable[_T]:
177
+ """Find the maximum element.
178
+
179
+ Returns the maximum value in an observable sequence according to the
180
+ specified comparer or default greater than less than check.
181
+
182
+ Examples:
183
+ Fluent style:
184
+ >>> result = source.max()
185
+ >>> result = source.max(lambda x, y: x.value > y.value)
186
+
187
+ Equivalent pipe style:
188
+ >>> from reactivex import operators as ops
189
+ >>> result = source.pipe(ops.max())
190
+
191
+ Args:
192
+ comparer: Optional comparer function for comparing elements.
193
+
194
+ Returns:
195
+ An observable sequence containing a single element with the maximum
196
+ element in the source sequence.
197
+
198
+ See Also:
199
+ - :func:`max <reactivex.operators.max>`
200
+ - :meth:`min`
201
+ - :meth:`max_by`
202
+ """
203
+ from reactivex import operators as ops
204
+
205
+ return self._as_observable().pipe(ops.max(comparer))
206
+
207
+ def min_by(
208
+ self,
209
+ key_mapper: typing.Mapper[_T, _TKey],
210
+ comparer: typing.Comparer[_TKey] | None = None,
211
+ ) -> Observable[list[_T]]:
212
+ """Find all elements with the minimum key value.
213
+
214
+ Returns the elements in an observable sequence with the minimum key
215
+ value according to the specified comparer.
216
+
217
+ Examples:
218
+ Fluent style:
219
+ >>> result = source.min_by(lambda x: x.value)
220
+ >>> result = source.min_by(lambda x: x.age, lambda x, y: x < y)
221
+
222
+ Equivalent pipe style:
223
+ >>> from reactivex import operators as ops
224
+ >>> result = source.pipe(ops.min_by(lambda x: x.value))
225
+
226
+ Args:
227
+ key_mapper: A function to extract the key from each element.
228
+ comparer: Optional comparer function for comparing keys.
229
+
230
+ Returns:
231
+ An observable sequence containing a list of zero or more elements
232
+ that have a minimum key value.
233
+
234
+ See Also:
235
+ - :func:`min_by <reactivex.operators.min_by>`
236
+ - :meth:`min`
237
+ - :meth:`max_by`
238
+ """
239
+ from reactivex import operators as ops
240
+
241
+ return self._as_observable().pipe(ops.min_by(key_mapper, comparer))
242
+
243
+ def max_by(
244
+ self,
245
+ key_mapper: typing.Mapper[_T, _TKey],
246
+ comparer: typing.Comparer[_TKey] | None = None,
247
+ ) -> Observable[list[_T]]:
248
+ """Find all elements with the maximum key value.
249
+
250
+ Returns the elements in an observable sequence with the maximum key
251
+ value according to the specified comparer.
252
+
253
+ Examples:
254
+ Fluent style:
255
+ >>> result = source.max_by(lambda x: x.value)
256
+ >>> result = source.max_by(lambda x: x.age, lambda x, y: x > y)
257
+
258
+ Equivalent pipe style:
259
+ >>> from reactivex import operators as ops
260
+ >>> result = source.pipe(ops.max_by(lambda x: x.value))
261
+
262
+ Args:
263
+ key_mapper: A function to extract the key from each element.
264
+ comparer: Optional comparer function for comparing keys.
265
+
266
+ Returns:
267
+ An observable sequence containing a list of zero or more elements
268
+ that have a maximum key value.
269
+
270
+ See Also:
271
+ - :func:`max_by <reactivex.operators.max_by>`
272
+ - :meth:`max`
273
+ - :meth:`min_by`
274
+ """
275
+ from reactivex import operators as ops
276
+
277
+ return self._as_observable().pipe(ops.max_by(key_mapper, comparer))
@@ -0,0 +1,306 @@
1
+ """Multicasting operators mixin for Observable."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast, overload
6
+
7
+ from reactivex import abc, typing
8
+
9
+ if TYPE_CHECKING:
10
+ from reactivex.observable import Observable
11
+ from reactivex.observable.connectableobservable import ConnectableObservable
12
+
13
+ _T = TypeVar("_T", covariant=True)
14
+ _R = TypeVar("_R")
15
+
16
+
17
+ class MulticastingMixin(Generic[_T]):
18
+ """Mixin providing multicasting operators for Observable.
19
+
20
+ This mixin adds operators that share a single subscription among
21
+ multiple observers, including publish, replay, and multicast.
22
+ """
23
+
24
+ def _as_observable(self) -> Observable[_T]:
25
+ """Cast mixin instance to Observable preserving type parameter.
26
+
27
+ This is safe because this mixin is only ever used as part of the Observable
28
+ class through multiple inheritance. At runtime, `self` in mixin methods will
29
+ always be an Observable[_T] instance. The type checker cannot infer this
30
+ because it analyzes mixins in isolation.
31
+
32
+ Returns:
33
+ The instance cast to Observable[_T] for type-safe method access.
34
+ """
35
+ return cast("Observable[_T]", self)
36
+
37
+ def share(self) -> Observable[_T]:
38
+ """Share a single subscription among multiple observers.
39
+
40
+ This is an alias for a composed publish() and ref_count().
41
+ As long as there is at least one subscriber, this observable
42
+ will be subscribed and emitting data. When all subscribers have
43
+ unsubscribed, it will unsubscribe from the source.
44
+
45
+ Examples:
46
+ Fluent style:
47
+ >>> shared = source.share()
48
+
49
+ Equivalent pipe style:
50
+ >>> from reactivex import operators as ops
51
+ >>> shared = source.pipe(ops.share())
52
+
53
+ Returns:
54
+ An observable that shares a single subscription to the
55
+ underlying source.
56
+
57
+ See Also:
58
+ - :func:`share <reactivex.operators.share>`
59
+ - :meth:`publish`
60
+ - :meth:`ref_count`
61
+ """
62
+ from reactivex import operators as ops
63
+
64
+ return self._as_observable().pipe(ops.share())
65
+
66
+ @overload
67
+ def publish(self) -> ConnectableObservable[_T]: ...
68
+
69
+ @overload
70
+ def publish(
71
+ self, mapper: typing.Mapper[Observable[_T], Observable[_R]]
72
+ ) -> Observable[_R]: ...
73
+
74
+ def publish(
75
+ self, mapper: typing.Mapper[Observable[_T], Observable[_R]] | None = None
76
+ ) -> Observable[_R] | ConnectableObservable[_T]:
77
+ """Returns a connectable observable or maps through a selector.
78
+
79
+ Returns an observable sequence that is the result of invoking the
80
+ mapper on a connectable observable sequence that shares a single
81
+ subscription to the underlying sequence.
82
+
83
+ Examples:
84
+ Fluent style:
85
+ >>> connectable = source.publish()
86
+ >>> result = source.publish(lambda x: x.take(5))
87
+
88
+ Equivalent pipe style:
89
+ >>> from reactivex import operators as ops
90
+ >>> connectable = source.pipe(ops.publish())
91
+
92
+ Args:
93
+ mapper: Optional selector function which can use the
94
+ multicasted source sequence.
95
+
96
+ Returns:
97
+ An observable sequence that contains the elements of a
98
+ sequence produced by multicasting the source sequence within
99
+ a mapper function, or a connectable observable if no mapper
100
+ is specified.
101
+
102
+ See Also:
103
+ - :func:`publish <reactivex.operators.publish>`
104
+ - :meth:`share`
105
+ - :meth:`multicast`
106
+ """
107
+ from reactivex import operators as ops
108
+
109
+ if mapper is None:
110
+ return self._as_observable().pipe(ops.publish())
111
+ return self._as_observable().pipe(ops.publish(mapper))
112
+
113
+ @overload
114
+ def replay(
115
+ self,
116
+ buffer_size: int | None = None,
117
+ window: typing.RelativeTime | None = None,
118
+ *,
119
+ scheduler: abc.SchedulerBase | None = None,
120
+ ) -> ConnectableObservable[_T]: ...
121
+
122
+ @overload
123
+ def replay(
124
+ self,
125
+ buffer_size: int | None = None,
126
+ window: typing.RelativeTime | None = None,
127
+ *,
128
+ mapper: typing.Mapper[Observable[_T], Observable[_R]],
129
+ scheduler: abc.SchedulerBase | None = None,
130
+ ) -> Observable[_R]: ...
131
+
132
+ def replay(
133
+ self,
134
+ buffer_size: int | None = None,
135
+ window: typing.RelativeTime | None = None,
136
+ *,
137
+ mapper: typing.Mapper[Observable[_T], Observable[_R]] | None = None,
138
+ scheduler: abc.SchedulerBase | None = None,
139
+ ) -> Observable[_R] | ConnectableObservable[_T]:
140
+ """Replay emissions to new subscribers.
141
+
142
+ Returns an observable sequence that is the result of invoking the
143
+ mapper on a connectable observable sequence that shares a single
144
+ subscription to the underlying sequence and starts with an initial
145
+ value. Replays values to new subscribers.
146
+
147
+ Examples:
148
+ Fluent style:
149
+ >>> connectable = source.replay()
150
+ >>> connectable = source.replay(buffer_size=3)
151
+ >>> result = source.replay(mapper=lambda x: x.take(5))
152
+
153
+ Equivalent pipe style:
154
+ >>> from reactivex import operators as ops
155
+ >>> connectable = source.pipe(ops.replay())
156
+
157
+ Args:
158
+ buffer_size: Maximum element count of the replay buffer.
159
+ window: Maximum time length of the replay buffer.
160
+ mapper: Selector function which can use the multicasted source.
161
+ scheduler: Scheduler to use for replay timing.
162
+
163
+ Returns:
164
+ An observable sequence that contains the elements of a
165
+ sequence produced by multicasting the source sequence within
166
+ a mapper function, or a connectable observable if no mapper
167
+ is specified.
168
+
169
+ See Also:
170
+ - :func:`replay <reactivex.operators.replay>`
171
+ - :meth:`publish`
172
+ - :meth:`share`
173
+ """
174
+ from reactivex import operators as ops
175
+
176
+ if mapper is None:
177
+ return self._as_observable().pipe(
178
+ ops.replay(buffer_size, window, scheduler=scheduler)
179
+ )
180
+ return self._as_observable().pipe(
181
+ ops.replay(buffer_size, window, mapper=mapper, scheduler=scheduler)
182
+ )
183
+
184
+ def multicast(
185
+ self,
186
+ subject: abc.SubjectBase[_T] | None = None,
187
+ ) -> Observable[_T]:
188
+ """Multicast through a subject.
189
+
190
+ Multicasts the source sequence notifications through an
191
+ instantiated subject.
192
+
193
+ Examples:
194
+ Fluent style:
195
+ >>> from reactivex.subject import Subject
196
+ >>> connectable = source.multicast(Subject())
197
+
198
+ Equivalent pipe style:
199
+ >>> from reactivex import operators as ops
200
+ >>> connectable = source.pipe(ops.multicast(Subject()))
201
+
202
+ Args:
203
+ subject: The subject to multicast through. If None, creates
204
+ a new subject.
205
+
206
+ Returns:
207
+ A connectable observable sequence that upon connection causes
208
+ the source sequence to push results into the specified subject.
209
+
210
+ See Also:
211
+ - :func:`multicast <reactivex.operators.multicast>`
212
+ - :meth:`publish`
213
+ - :meth:`share`
214
+ """
215
+ from reactivex import operators as ops
216
+
217
+ if subject is None:
218
+ return self._as_observable().pipe(ops.multicast())
219
+ return self._as_observable().pipe(ops.multicast(subject))
220
+
221
+ def ref_count(self) -> Observable[_T]:
222
+ """Manage subscriptions to a connectable observable.
223
+
224
+ Returns an observable sequence that stays connected to the
225
+ source as long as there is at least one subscription to the
226
+ observable sequence.
227
+
228
+ Examples:
229
+ Fluent style:
230
+ >>> result = source.publish().ref_count()
231
+
232
+ Equivalent pipe style:
233
+ >>> from reactivex import operators as ops
234
+ >>> result = source.pipe(ops.publish(), ops.ref_count())
235
+
236
+ Returns:
237
+ An observable sequence that stays connected to the source.
238
+
239
+ See Also:
240
+ - :func:`ref_count <reactivex.operators.ref_count>`
241
+ - :meth:`share`
242
+ - :meth:`publish`
243
+ """
244
+ from reactivex import operators as ops
245
+
246
+ # Cast is safe: ref_count is meant to be called on ConnectableObservable
247
+ # instances (the result of publish/multicast). The fluent API allows
248
+ # chaining this after publish(). We call the operator directly to avoid
249
+ # type variance issues with pipe's generic parameters.
250
+ source = cast("ConnectableObservable[_T]", self._as_observable())
251
+ return ops.ref_count()(source)
252
+
253
+ @overload
254
+ def publish_value(self, initial_value: Any) -> ConnectableObservable[Any]: ...
255
+
256
+ @overload
257
+ def publish_value(
258
+ self,
259
+ initial_value: Any,
260
+ mapper: typing.Mapper[Observable[Any], Observable[_R]],
261
+ ) -> Observable[_R]: ...
262
+
263
+ def publish_value(
264
+ self,
265
+ initial_value: Any,
266
+ mapper: typing.Mapper[Observable[Any], Observable[_R]] | None = None,
267
+ ) -> Observable[_R] | ConnectableObservable[Any]:
268
+ """Multicast with an initial value (BehaviorSubject).
269
+
270
+ Returns an observable sequence that is the result of invoking
271
+ the mapper on a connectable observable sequence that shares a
272
+ single subscription to the underlying sequence and starts with
273
+ initial_value.
274
+
275
+ This is essentially publish with a BehaviorSubject.
276
+
277
+ Examples:
278
+ Fluent style:
279
+ >>> connectable = source.publish_value(0)
280
+ >>> result = source.publish_value(0, lambda x: x.take(5))
281
+
282
+ Equivalent pipe style:
283
+ >>> from reactivex import operators as ops
284
+ >>> connectable = source.pipe(ops.publish_value(0))
285
+
286
+ Args:
287
+ initial_value: Initial value to emit before source emissions.
288
+ mapper: Optional selector function which can use the
289
+ multicasted source sequence.
290
+
291
+ Returns:
292
+ An observable sequence that contains the elements of a
293
+ sequence produced by multicasting the source sequence within
294
+ a mapper function, or a connectable observable if no mapper
295
+ is specified.
296
+
297
+ See Also:
298
+ - :func:`publish_value <reactivex.operators.publish_value>`
299
+ - :meth:`publish`
300
+ - :meth:`replay`
301
+ """
302
+ from reactivex import operators as ops
303
+
304
+ if mapper is None:
305
+ return self._as_observable().pipe(ops.publish_value(initial_value))
306
+ return self._as_observable().pipe(ops.publish_value(initial_value, mapper))