Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #572 - Allow appending rows after a dynamic column was inserted #573

Merged
merged 4 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/tablib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ def __init__(self, *args, **kwargs):
# (column, callback) tuples
self._formatters = []

# {col_index: col_func}
self._dyn_columns = {}
claudep marked this conversation as resolved.
Show resolved Hide resolved

self.headers = kwargs.get('headers')

self.title = kwargs.get('title')
Expand Down Expand Up @@ -238,7 +241,7 @@ def _set_in_format(self, fmt_key, in_stream, **kwargs):
def _validate(self, row=None, col=None, safety=False):
"""Assures size of every row in dataset is of proper proportions."""
if row:
is_valid = (len(row) == self.width) if self.width else True
is_valid = (len(row) == (self.width - len(self._dyn_columns))) if self.width else True
claudep marked this conversation as resolved.
Show resolved Hide resolved
elif col:
if len(col) < 1:
is_valid = True
Expand Down Expand Up @@ -449,6 +452,9 @@ def insert(self, index, row, tags=()):
"""

self._validate(row)
for pos, func in self._dyn_columns.items():
claudep marked this conversation as resolved.
Show resolved Hide resolved
row = list(row)
row.insert(pos, func(row))
self._data.insert(index, Row(row, tags=tags))

def rpush(self, row, tags=()):
Expand Down Expand Up @@ -547,6 +553,7 @@ def insert_col(self, index, col=None, header=None):

# Callable Columns...
if hasattr(col, '__call__'):
self._dyn_columns[self.width] = col
claudep marked this conversation as resolved.
Show resolved Hide resolved
col = list(map(col, self._data))

col = self._clean_col(col)
Expand Down
6 changes: 6 additions & 0 deletions tests/test_tablib.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ def new_col(x):
return x[0]

self.founders.append_col(new_col, header='first_again')
# A new row can still be appended, and the dynamic column value generated.
claudep marked this conversation as resolved.
Show resolved Hide resolved
self.founders.append(('Some', 'One', 71))
self.assertEqual(
self.founders['first_again'],
['John', 'George', 'Thomas', 'Some']
)

def test_header_slicing(self):
"""Verify slicing by headers."""
Expand Down