Skip to content

Commit be9bfcc

Browse files
authored
Merge pull request #92 from dbcli/RW/add-headerless-csv-formats
Add headerless variants of CSV and TSV formats
2 parents e4fe506 + 3f8ae6d commit be9bfcc

File tree

5 files changed

+61
-9
lines changed

5 files changed

+61
-9
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Changelog
22

3+
- Added noheader CSV and TSV output formats.
4+
35
## Version 2.4.0
46

57
(released on 2025-03-10)

cli_helpers/tabular_output/delimited_output_adapter.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from cli_helpers.utils import filter_dict_by_key
99
from .preprocessors import bytes_to_string, override_missing_value
1010

11-
supported_formats = ("csv", "csv-tab")
11+
supported_formats = ("csv", "csv-tab", "csv-noheader", "csv-tab-noheader")
1212
preprocessors = (override_missing_value, bytes_to_string)
1313

1414

@@ -35,9 +35,9 @@ def adapter(data, headers, table_format="csv", **kwargs):
3535
"skipinitialspace",
3636
"strict",
3737
)
38-
if table_format == "csv":
38+
if table_format in ("csv", "csv-noheader"):
3939
delimiter = ","
40-
elif table_format == "csv-tab":
40+
elif table_format in ("csv-tab", "csv-tab-noheader"):
4141
delimiter = "\t"
4242
else:
4343
raise ValueError("Invalid table_format specified.")
@@ -47,8 +47,9 @@ def adapter(data, headers, table_format="csv", **kwargs):
4747

4848
l = linewriter()
4949
writer = csv.writer(l, **ckwargs)
50-
writer.writerow(headers)
51-
yield l.line
50+
if "noheader" not in table_format:
51+
writer.writerow(headers)
52+
yield l.line
5253

5354
for row in data:
5455
l.reset()

cli_helpers/tabular_output/tsv_output_adapter.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@
77
from itertools import chain
88
from cli_helpers.utils import replace
99

10-
supported_formats = ("tsv",)
10+
supported_formats = ("tsv", "tsv_noheader")
1111
preprocessors = (override_missing_value, bytes_to_string, convert_to_string)
1212

1313

14-
def adapter(data, headers, **kwargs):
14+
def adapter(data, headers, table_format="tsv", **kwargs):
1515
"""Wrap the formatting inside a function for TabularOutputFormatter."""
16-
for row in chain((headers,), data):
17-
yield "\t".join((replace(r, (("\n", r"\n"), ("\t", r"\t"))) for r in row))
16+
if table_format == "tsv":
17+
for row in chain((headers,), data):
18+
yield "\t".join((replace(r, (("\n", r"\n"), ("\t", r"\t"))) for r in row))
19+
elif table_format == "tsv_noheader":
20+
for row in data:
21+
yield "\t".join((replace(r, (("\n", r"\n"), ("\t", r"\t"))) for r in row))
22+
else:
23+
raise ValueError(f"Invalid table_format specified: {table_format}.")

tests/tabular_output/test_delimited_output_adapter.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,36 @@ def test_csv_wrapper():
4242
list(output)
4343

4444

45+
def test_csv_noheader_wrapper():
46+
"""Test the delimited output adapter without headers."""
47+
# Test comma-delimited output.
48+
data = [["abc", "1"], ["d", "456"]]
49+
headers = ["letters", "number"]
50+
output = delimited_output_adapter.adapter(
51+
iter(data),
52+
headers,
53+
table_format="csv-noheader",
54+
dialect="unix",
55+
)
56+
assert "\n".join(output) == dedent(
57+
'''\
58+
"abc","1"\n\
59+
"d","456"'''
60+
)
61+
62+
# Test tab-delimited output.
63+
data = [["abc", "1"], ["d", "456"]]
64+
headers = ["letters", "number"]
65+
output = delimited_output_adapter.adapter(
66+
iter(data), headers, table_format="csv-tab-noheader", dialect="unix"
67+
)
68+
assert "\n".join(output) == dedent(
69+
'''\
70+
"abc"\t"1"\n\
71+
"d"\t"456"'''
72+
)
73+
74+
4575
def test_unicode_with_csv():
4676
"""Test that the csv wrapper can handle non-ascii characters."""
4777
data = [["观音", "1"], ["Ποσειδῶν", "456"]]

tests/tabular_output/test_tsv_output_adapter.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ def test_tsv_wrapper():
2323
)
2424

2525

26+
def test_tsv_headerless_wrapper():
27+
"""Test the tsv headerless_output adapter."""
28+
# Test tab-delimited output.
29+
data = [["ab\r\nc", "1"], ["d", "456"]]
30+
headers = ["letters", "number"]
31+
output = tsv_output_adapter.adapter(iter(data), headers, table_format="tsv_noheader")
32+
assert "\n".join(output) == dedent(
33+
"""\
34+
ab\r\\nc\t1\n\
35+
d\t456"""
36+
)
37+
38+
2639
def test_unicode_with_tsv():
2740
"""Test that the tsv wrapper can handle non-ascii characters."""
2841
data = [["观音", "1"], ["Ποσειδῶν", "456"]]

0 commit comments

Comments
 (0)