diff --git a/todoman/formatters.py b/todoman/formatters.py index 9ba4c956..3e7d185e 100644 --- a/todoman/formatters.py +++ b/todoman/formatters.py @@ -85,13 +85,23 @@ def compact_multiple(self, todos): return tabulate(table, tablefmt='plain') - def _columnize(self, label, text): + def _columnize_text(self, label, text): + """Display text, split text by line-endings, on multiple colums,""" + """do nothing if text is empty or None""" + lines = text.splitlines() if text else None + + return self._columnize_list(label, lines) + + def _columnize_list(self, label, lst): + """Display list on multiple columns,""" + """do nothing if list is empty or None""" + rows = [] - lines = text.splitlines() - rows.append([label, lines[0]]) - for line in lines[1:]: - rows.append([None, line]) + if lst: + rows.append([label, lst[0]]) + for line in lst[1:]: + rows.append([None, line]) return rows @@ -102,10 +112,8 @@ def detailed(self, todo): :param Todo todo: The todo component. """ extra_rows = [] - if todo.description: - extra_rows += self._columnize('Description', todo.description) - if todo.location: - extra_rows += self._columnize('Location', todo.location) + extra_rows += self._columnize_text('Description', todo.description) + extra_rows += self._columnize_text('Location', todo.location) if extra_rows: return '{}\n\n{}'.format( diff --git a/todoman/model.py b/todoman/model.py index 024dd582..10a71b40 100644 --- a/todoman/model.py +++ b/todoman/model.py @@ -160,19 +160,44 @@ def clone(self): ) def __setattr__(self, name, value): - # Avoids accidentally setting a field to None when that's not a valid - # attribute. - if not value: - if name in Todo.RRULE_FIELDS: - return object.__setattr__(self, name, '') - if name in Todo.STRING_FIELDS: - return object.__setattr__(self, name, '') - if name in Todo.INT_FIELDS: - return object.__setattr__(self, name, 0) - if name in Todo.LIST_FIELDS: - return object.__setattr__(self, name, []) - - return object.__setattr__(self, name, value) + """Check type and avoid setting fields to None""" + """when that is not a valid attribue.""" + + v = value + + if name in Todo.RRULE_FIELDS: + if value is None: + v = '' + else: + assert isinstance(value, str), ( + "Got {0} for {1} where str was expected" + .format(type(value), name)) + + if name in Todo.STRING_FIELDS: + if value is None: + v = '' + else: + assert isinstance(value, str), ( + "Got {0} for {1} where str was expected" + .format(type(value), name)) + + if name in Todo.INT_FIELDS: + if value is None: + v = 0 + else: + assert isinstance(value, int), ( + "Got {0} for {1} where int was expected" + .format(type(value), name)) + + if name in Todo.LIST_FIELDS: + if value is None: + v = [] + else: + assert isinstance(value, list), ( + "Got {0} for {1} where list was expected" + .format(type(value), name)) + + return object.__setattr__(self, name, v) @property def is_completed(self):