From 1dbcf2cc0d934c72ff583e9a515b9848286b1666 Mon Sep 17 00:00:00 2001 From: Daniele Nicolodi Date: Fri, 24 Jan 2025 14:00:40 +0100 Subject: [PATCH] importers.csvbase: Allow to specifying a default value Add to all implemented column types the possibility to specify a default value to return when the parsed field is empty. When a default is not specified, the empty field is passed to the parser to generate a value. --- beangulp/importers/csvbase.py | 16 +++++++----- beangulp/importers/csvbase_test.py | 42 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/beangulp/importers/csvbase.py b/beangulp/importers/csvbase.py index 2cd7b00..f2bb6d6 100644 --- a/beangulp/importers/csvbase.py +++ b/beangulp/importers/csvbase.py @@ -99,10 +99,11 @@ class Columns(Column): Args: name: Column names or indexes. sep: Separator to use to join columns. + default: Value to return all the fields are empty, if specified. """ - def __init__(self, *names, sep=' '): - super().__init__(*names) + def __init__(self, *names, sep=' ', default=NA): + super().__init__(*names, default=default) self.sep = sep def parse(self, *values): @@ -119,10 +120,11 @@ class Date(Column): Args: name: Column name or index. frmt: Date format specification. + default: Value to return if the field is empty, if specified. """ - def __init__(self, name, frmt='%Y-%m-%d'): - super().__init__(name) + def __init__(self, name, frmt='%Y-%m-%d', default=NA): + super().__init__(name, default=default) self.frmt = frmt def parse(self, value): @@ -142,11 +144,11 @@ class Amount(Column): subs: Dictionary mapping regular expression patterns to replacement strings. Substitutions are performed with re.sub() in the order they are specified. + default: Value to return if the field is empty, if specified. """ - - def __init__(self, name, subs=None): - super().__init__(name) + def __init__(self, name, subs=None, default=NA): + super().__init__(name, default=default) self.subs = subs if subs is not None else {} def parse(self, value): diff --git a/beangulp/importers/csvbase_test.py b/beangulp/importers/csvbase_test.py index ee936e9..ea64de0 100644 --- a/beangulp/importers/csvbase_test.py +++ b/beangulp/importers/csvbase_test.py @@ -63,6 +63,18 @@ def test_custom_format(self): value = func(('16.05.2021', )) self.assertEqual(value, datetime.date(2021, 5, 16)) + def test_default_value(self): + column = Date(0, default=datetime.date.today()) + func = column.getter(None) + value = func(('', )) + self.assertEqual(value, datetime.date.today()) + + def test_default_value_none(self): + column = Date(0, default=None) + func = column.getter(None) + value = func(('', )) + self.assertIsNone(value) + class TestColumnsColumn(unittest.TestCase): @@ -78,6 +90,24 @@ def test_custom_sep(self): value = func(('0', '1', '2', '3', )) self.assertEqual(value, '0: 1') + def test_default_value(self): + column = Columns(0, 1, default='something') + func = column.getter(None) + value = func(('', '', )) + self.assertEqual(value, 'something') + + def test_default_value_none(self): + column = Columns(0, 1, default=None) + func = column.getter(None) + value = func(('', '', )) + self.assertIsNone(value) + + def test_some_empty(self): + column = Columns(0, 1, default=None) + func = column.getter(None) + value = func(('this', '', )) + self.assertEqual(value, 'this') + class TestAmountColumn(unittest.TestCase): @@ -109,6 +139,18 @@ def test_parse_subs_currency(self): self.assertIsInstance(value, decimal.Decimal) self.assertEqual(value, decimal.Decimal('1000.00')) + def test_default_value(self): + column = Amount(0, default=decimal.Decimal(42)) + func = column.getter(None) + value = func(('', )) + self.assertEqual(value, decimal.Decimal(42)) + + def test_default_value_none(self): + column = Amount(0, default=None) + func = column.getter(None) + value = func(('', )) + self.assertIsNone(value) + class TestCSVMeta(unittest.TestCase):