Skip to content

Commit

Permalink
output.ToCSV updates context when data has a method_update_context(co…
Browse files Browse the repository at this point in the history
…ntext). Add ToCSV tests.
  • Loading branch information
ynikitenko committed Apr 18, 2022
1 parent 651d957 commit b2cb0c7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
10 changes: 5 additions & 5 deletions lena/output/to_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ def run(self, flow):
"""Convert values from *flow* to CSV text.
*context.output* is updated with {"filetype": "csv"}.
If a data structure has a method *\\_update_context(context)*,
it also updates the current context during the transform.
All not converted data is yielded unchanged.
If *context.output.to_csv* is ``False``, the value is skipped.
Expand All @@ -209,11 +211,6 @@ def run(self, flow):
use :func:`hist1d_to_csv`, :func:`hist2d_to_csv`
or :func:`iterable_to_table`.
"""
def is_writable_hist(val):
"""Test whether a value from flow can be converted to CSV."""
data, context = lena.flow.get_data_context(val)
return isinstance(data, lena.structures.histogram)

for val in flow:
data, context = lena.flow.get_data_context(val)

Expand Down Expand Up @@ -271,6 +268,9 @@ def is_writable_hist(val):
data, row_separator=self._separator, header=self._header
)
csv = "\n".join(rows)
if (hasattr(data, "_update_context") and
callable(data._update_context)):
data._update_context(context)
lena.context.update_recursively(context, "output.filetype.csv")
yield (csv, context)
continue
Expand Down
6 changes: 4 additions & 2 deletions lena/structures/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,10 @@ def _update_context(self, context):
Existing values are not removed
from *context.value* and its subcontexts.
Called on destruction of the graph (for example,
in :class:`.ToCSV`).
Called on "destruction" of the graph (for example,
in :class:`.ToCSV`). By destruction we mean conversion
to another structure (like text) in the flow.
The graph object is not really destroyed in this process.
"""
# this method is private, because we encourage users to yield
# graphs into the flow and process them with ToCSV element
Expand Down
26 changes: 21 additions & 5 deletions tests/output/test_to_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,36 @@ def test_iterable_to_table():

def test_to_csv():
hist = histogram(edges=[0, 1, 2], bins=[1, 2])
gr = graph([[0, 1], [2.5, 3]])
gr0 = graph([[0, 1], [2.5, 3]])
to_csv = ToCSV(separator=",", header=None, duplicate_last_bin=True)

## histogram and iterables work, other values passed unchanged
# no context works fine
res1 = list(to_csv.run([hist, gr, 3]))
res0 = list(to_csv.run([hist, gr0, 3, "a string"]))
# data parts are correct
data_1 = [res1[0][0], res1[1][0], res1[2]]
data_0 = [res0[0][0], res0[1][0]]
# assert list(to_csv.run([hist, gr, 3])) == []
assert data_1 == [
assert data_0 == [
'0.000000,1.000000\n1.000000,2.000000\n2.000000,2.000000',
'0,2.5\n1,3',
3
]
assert res0[2:] == [3, "a string"]

# no error fields
assert res0[1][1] == {'output': {'filetype': 'csv'}}

# data._update_context is called
gr1 = graph([[0, 1], [2.5, 3], [0.1, 0.1]], field_names="x,y,error_y")
res1 = list(to_csv.run([gr1]))[0]
assert res1[1] == {
'output': {'filetype': 'csv'},
'error': {'y': {'index': 2}}
}

# context.to_csv.False forbids the transform
no_to_csv_context = {"output": {"to_csv": False}}
res2 = list(to_csv.run([(gr0, no_to_csv_context)]))[0]
assert res2 == (gr0, no_to_csv_context)


def test_hist_to_csv():
Expand Down

0 comments on commit b2cb0c7

Please sign in to comment.