Skip to content

Commit 52e6d36

Browse files
committed
Fixes problem with handling named tuples
1 parent 53804e1 commit 52e6d36

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

tableformatter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,12 @@ def generate_table(self, entries: Iterable[Union[Iterable, object]], force_trans
995995
if self._row_tagger is not None:
996996
entry_opts = self._row_tagger(entry_obj)
997997
else:
998-
entry_obj = entry[0]
998+
# check if this is a tuple containing a dictionary of decorated values. If so, the row object
999+
# is the first element a the decorated values is the second element.
1000+
if len(entry) == 2 and isinstance(entry[1], dict):
1001+
entry_obj = entry[0]
1002+
else:
1003+
entry_obj = entry
9991004
if self._row_tagger is not None:
10001005
entry_opts = self._row_tagger(entry_obj)
10011006
if len(entry) == 2 and isinstance(entry[1], dict):

tests/test_rows.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pytest
88

99
import tableformatter as tf
10+
from collections import namedtuple
1011

1112
# Make the test results reproducible regardless of what color libraries are installed
1213
tf.TableColors.set_color_library('none')
@@ -26,11 +27,19 @@ def get_field3(self):
2627
return self._field3
2728

2829

30+
NamedTupleRow = namedtuple('NamedTupleRow', 'field1,field2,field3,field4')
31+
"""Example named tuple to demonstrate usage with TableFormatter"""
32+
33+
2934
def multiply(row_obj: MyRowObject):
3035
"""Demonstrates an object formatter function"""
3136
return str(row_obj.get_field3() * row_obj.field4)
3237

3338

39+
def multiply_named_tuple(row_job):
40+
return str(row_job.field3 * row_job.field4)
41+
42+
3443
def multiply_tuple(row_obj):
3544
"""Demonstrates an object formatter function"""
3645
return str(row_obj[2] * row_obj[3])
@@ -117,6 +126,38 @@ def test_obj_rows():
117126
assert table == expected
118127

119128

129+
def test_namedtuple_rows():
130+
expected = '''
131+
╔══════════════════════╤════════╤═════╤═══════╤════════════╗
132+
║ │ │ Num │ │ ║
133+
║ First │ Second │ 1 │ Num 2 │ Multiplied ║
134+
╠══════════════════════╪════════╪═════╪═══════╪════════════╣
135+
║ RLonger text that │ RA2 │ R5 │ R56 │ R280 ║
136+
║ Rwill trigger the │ │ │ │ ║
137+
║ Rcolumn wrapping │ │ │ │ ║
138+
║ GB1 │ GB2 │ G23 │ G8 │ G184 ║
139+
║ │ GB2 │ │ │ ║
140+
║ │ GB2 │ │ │ ║
141+
║ C1 │ C2 │ 4 │ 9 │ 36 ║
142+
║ D1 │ D2 │ 7 │ 5 │ 35 ║
143+
╚══════════════════════╧════════╧═════╧═══════╧════════════╝
144+
'''.lstrip('\n')
145+
rows = [tf.Row(NamedTupleRow('Longer text that will trigger the column wrapping', 'A2', 5, 56),
146+
text_color='R'),
147+
tf.Row(NamedTupleRow('B1', 'B2\nB2\nB2', 23, 8),
148+
text_color='G'),
149+
NamedTupleRow('C1', 'C2', 4, 9),
150+
NamedTupleRow('D1', 'D2', 7, 5)]
151+
152+
columns = (tf.Column('First', width=20, attrib='field1'),
153+
tf.Column('Second', attrib='field2'),
154+
tf.Column('Num 1', width=3, attrib='field3'),
155+
tf.Column('Num 2', attrib='field4'),
156+
tf.Column('Multiplied', obj_formatter=multiply_named_tuple))
157+
table = tf.generate_table(rows, columns)
158+
assert table == expected
159+
160+
120161
def test_tuple_rows():
121162
expected = '''
122163
╔══════════════════════╤════════╤═══════╤═══════════╤════════════╗

0 commit comments

Comments
 (0)