Skip to content

Commit

Permalink
csvlook: Add --max-precision and --no-number-ellipsis options, closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmckinney committed Oct 18, 2023
1 parent e5ef16e commit f10e3b8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Unreleased
----------

* :doc:`/scripts/csvformat` adds a :code:`--skip-header` (:code:`-E`) option to not output a header row.
* :doc:`/scripts/csvlook` adds a :code:`--max-precision` option to set the maximum number of decimal places to display.
* :doc:`/scripts/csvlook` adds a :code:`--no-number-ellipsis` option to disable the ellipsis (````) if :code:`--max-precision` is exceeded. (Requires agate 1.9.0 or greater.)
* :doc:`/scripts/csvstat` supports the :code:`--no-inference` (:code:`-I`), :code:`--locale` (:code:`-L`), :code:`--blanks`, :code:`--date-format` and :code:`datetime-format` options.
* :doc:`/scripts/csvstat` adds a :code:`--json` option to output results as JSON text.
* :doc:`/scripts/csvstat` adds an :code:`--indent` option to indent the JSON text when :code:`--json` is set.
Expand Down
16 changes: 16 additions & 0 deletions csvkit/utilities/csvlook.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python

import agate
from agate import config

from csvkit.cli import CSVKitUtility

Expand All @@ -18,6 +19,12 @@ def add_arguments(self):
self.argparser.add_argument(
'--max-column-width', dest='max_column_width', type=int,
help='Truncate all columns to at most this width. The remainder will be replaced with ellipsis.')
self.argparser.add_argument(
'--max-precision', dest='max_precision', type=int,
help='The maximum number of decimal places to display. The remainder will be replaced with ellipsis.')
self.argparser.add_argument(
'--no-number-ellipsis', dest='no_number_ellipsis', action='store_true',
help='Disable the ellipsis if --max-precision is exceeded.')
self.argparser.add_argument(
'-y', '--snifflimit', dest='sniff_limit', type=int, default=1024,
help='Limit CSV dialect sniffing to the specified number of bytes. '
Expand All @@ -30,6 +37,14 @@ def main(self):
if self.additional_input_expected():
self.argparser.error('You must provide an input file or piped data.')

kwargs = {}
# In agate, max_precision defaults to 3. None means infinity.
if self.args.max_precision is not None:
kwargs['max_precision'] = self.args.max_precision

if self.args.no_number_ellipsis:
config.set_option('number_truncation_chars', '')

sniff_limit = self.args.sniff_limit if self.args.sniff_limit != -1 else None
table = agate.Table.from_csv(
self.input_file,
Expand All @@ -45,6 +60,7 @@ def main(self):
max_rows=self.args.max_rows,
max_columns=self.args.max_columns,
max_column_width=self.args.max_column_width,
**kwargs,
)


Expand Down
4 changes: 4 additions & 0 deletions docs/scripts/csvlook.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Renders a CSV to the command line in a Markdown-compatible, fixed-width format:
--max-column-width MAX_COLUMN_WIDTH
Truncate all columns to at most this width. The
remainder will be replaced with ellipsis.
--max-precision MAX_PRECISION
The maximum number of decimal places to display. The
remainder will be replaced with ellipsis.
--no-number-ellipsis Disable the ellipsis if --max-precision is exceeded.
-y SNIFF_LIMIT, --snifflimit SNIFF_LIMIT
Limit CSV dialect sniffing to the specified number of
bytes. Specify "0" to disable sniffing entirely, or
Expand Down
2 changes: 2 additions & 0 deletions examples/test_precision.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a
1.234567
26 changes: 26 additions & 0 deletions tests/test_utilities/test_csvlook.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
import sys
from unittest.mock import patch

from agate import config

from csvkit.utilities.csvlook import CSVLook, launch_new_instance
from tests.utils import CSVKitTestCase, EmptyFileTests, stdin_as_string


class TestCSVLook(CSVKitTestCase, EmptyFileTests):
Utility = CSVLook

def tearDown(self):
config.set_option('truncation_chars', '…')

def test_launch_new_instance(self):
with patch.object(sys, 'argv', [self.Utility.__name__.lower(), 'examples/dummy.csv']):
launch_new_instance()
Expand Down Expand Up @@ -126,6 +131,27 @@ def test_max_column_width(self):
'| Tr... | 2 | 3 |',
])

def test_max_precision(self):
self.assertLines(['--max-precision', '0', 'examples/test_precision.csv'], [
'| a |',
'| -- |',
'| 1… |',
])

def test_no_number_ellipsis(self):
self.assertLines(['--no-number-ellipsis', 'examples/test_precision.csv'], [
'| a |',
'| ----- |',
'| 1.235 |',
])

def test_max_precision_no_number_ellipsis(self):
self.assertLines(['--max-precision', '0', '--no-number-ellipsis', 'examples/test_precision.csv'], [
'| a |',
'| - |',
'| 1 |',
])

def test_stdin(self):
input_file = io.BytesIO(b'a,b,c\n1,2,3\n4,5,6\n')

Expand Down

0 comments on commit f10e3b8

Please sign in to comment.