Skip to content

Commit 5c1b3a6

Browse files
committed
imporved docs, comments, updated tests
1 parent 6ecd2c9 commit 5c1b3a6

2 files changed

Lines changed: 31 additions & 17 deletions

File tree

streamz/sinks.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import inspect
2+
import weakref
3+
14
from tornado import gen
25

36
from streamz import Stream
47

8+
# sinks add themselves here to avoid being garbage-collected
59
_global_sinks = set()
610

711

@@ -18,6 +22,16 @@ def __init__(self, upstream, **kwargs):
1822
class sink(Sink):
1923
""" Apply a function on every element
2024
25+
Parameters
26+
----------
27+
func: callable
28+
A function that will be applied on every element.
29+
args:
30+
Positional arguments that will be passed to ``func`` after the incoming element.
31+
kwargs:
32+
Stream-specific arguments will be passed to ``Stream.__init__``, the rest of
33+
them will be passed to ``func``.
34+
2135
Examples
2236
--------
2337
>>> source = Stream()
@@ -40,10 +54,11 @@ class sink(Sink):
4054
def __init__(self, upstream, func, *args, **kwargs):
4155
self.func = func
4256
# take the stream specific kwargs out
43-
stream_name = kwargs.pop("stream_name", None)
44-
self.kwargs = kwargs
57+
sig = set(inspect.signature(Stream).parameters)
58+
stream_kwargs = {k: v for (k, v) in kwargs.items() if k in sig}
59+
self.kwargs = {k: v for (k, v) in kwargs.items() if k not in sig}
4560
self.args = args
46-
super().__init__(upstream, stream_name=stream_name)
61+
super().__init__(upstream, **stream_kwargs)
4762

4863
def update(self, x, who=None, metadata=None):
4964
result = self.func(x, *self.args, **self.kwargs)
@@ -59,8 +74,8 @@ class sink_to_textfile(Sink):
5974
6075
Type of elements must be ``str``.
6176
62-
Arguments
63-
---------
77+
Parameters
78+
----------
6479
file: str or file-like
6580
File to write the elements to. ``str`` is treated as a file name to open.
6681
If file-like, descriptor must be open in text mode. Note that the file
@@ -83,14 +98,14 @@ class sink_to_textfile(Sink):
8398
1
8499
"""
85100
def __init__(self, upstream, file, end="\n", mode="a", **kwargs):
86-
self._fp = open(file, mode=mode, buffering=1) if isinstance(file, str) else file
87101
self._end = end
102+
self._fp = open(file, mode=mode) if isinstance(file, str) else file
103+
weakref.finalize(self, self._fp.close)
88104
super().__init__(upstream, ensure_io_loop=True, **kwargs)
89105

90106
def __del__(self):
91107
self._fp.close()
92108

93109
@gen.coroutine
94110
def update(self, x, who=None, metadata=None):
95-
yield self.loop.run_in_executor(None, self._fp.write, x)
96-
yield self.loop.run_in_executor(None, self._fp.write, self._end)
111+
yield self.loop.run_in_executor(None, self._fp.write, x + self._end)

streamz/tests/test_sinks.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from time import sleep
2-
31
import pytest
42
from streamz import Stream
53
from streamz.sinks import _global_sinks
@@ -16,33 +14,34 @@ def mycustomsink(elem, key, prefix=""):
1614
L[key].append(elem)
1715

1816
s = Stream()
19-
s.sink(mycustomsink, "cat", "super")
20-
17+
sink = s.sink(mycustomsink, "cat", "super", stream_name="test")
2118
s.emit(1)
2219
s.emit(2)
20+
2321
assert L['supercat'] == [1, 2]
22+
assert sink.name == "test"
2423

2524

2625
def test_sink_to_textfile_fp():
2726
source = Stream()
28-
with tmpfile() as filename, open(filename, "w", buffering=1) as fp:
27+
with tmpfile() as filename, open(filename, "w") as fp:
2928
source.map(str).sink_to_textfile(fp)
3029
source.emit(0)
3130
source.emit(1)
3231

33-
sleep(0.01)
32+
fp.flush()
3433

3534
assert open(filename, "r").read() == "0\n1\n"
3635

3736

3837
def test_sink_to_textfile_named():
3938
source = Stream()
4039
with tmpfile() as filename:
41-
source.map(str).sink_to_textfile(filename)
40+
_sink = source.map(str).sink_to_textfile(filename)
4241
source.emit(0)
4342
source.emit(1)
4443

45-
sleep(0.01)
44+
_sink._fp.flush()
4645

4746
assert open(filename, "r").read() == "0\n1\n"
4847

@@ -55,5 +54,5 @@ def test_sink_to_textfile_closes():
5554
_global_sinks.remove(sink)
5655
del sink
5756

58-
with pytest.raises(ValueError): # I/O operation on closed file
57+
with pytest.raises(ValueError, match=r"I/O operation on closed file\."):
5958
fp.write(".")

0 commit comments

Comments
 (0)