Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
42 changes: 28 additions & 14 deletions prettytable/prettytable.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ def _get_size(text):


class PrettyTable(object):
OPTIONS = [
'align', 'attributes', 'border', 'end', 'fields', 'float_format',
'format', 'header', 'header_style', 'horizontal_char', 'hrules',
'int_format', 'junction_char', 'left_padding_width',
'max_table_width', 'max_width', 'min_table_width', 'min_width',
'oldsortslice', 'padding_width', 'print_empty', 'reversesort',
'right_padding_width', 'sort_key', 'sortby', 'start', 'title',
'valign', 'vertical_char', 'vrules', 'xhtml'
]

def __init__(self, field_names=None, **kwargs):

"""Return a new PrettyTable instance
Expand Down Expand Up @@ -62,11 +72,13 @@ def __init__(self, field_names=None, **kwargs):
junction_char - single character string used to draw line junctions
sortby - name of field to sort rows by
sort_key - sorting key function, applied to data points before sorting
align - default align for each column (None, "l", "c", or "r"). If None, defaults to "c".
valign - default valign for each row (None, "t", "m" or "b")
reversesort - True or False to sort in descending or ascending order
oldsortslice - Slice rows before sorting in the "old style" """

self.encoding = kwargs.get("encoding", "UTF-8")
self._default_align = kwargs.get("align", "c")

# Data
self._field_names = []
Expand All @@ -82,14 +94,8 @@ def __init__(self, field_names=None, **kwargs):
else:
self._widths = []

# Options
self._options = "title start end fields header border sortby reversesort sort_key attributes format hrules vrules".split()
self._options.extend(
"int_format float_format min_table_width max_table_width padding_width left_padding_width right_padding_width".split())
self._options.extend(
"vertical_char horizontal_char junction_char header_style valign xhtml print_empty oldsortslice".split())
self._options.extend("align valign max_width min_width".split())
for option in self._options:
# Option validation
for option in PrettyTable.OPTIONS:
if option in kwargs:
self._validate_option(option, kwargs[option])
else:
Expand Down Expand Up @@ -198,7 +204,7 @@ def __getitem__(self, index):

new = PrettyTable()
new.field_names = self.field_names
for attr in self._options:
for attr in PrettyTable.OPTIONS:
setattr(new, "_" + attr, getattr(self, "_" + attr))
setattr(new, "_align", getattr(self, "_align"))
if isinstance(index, slice):
Expand Down Expand Up @@ -259,6 +265,10 @@ def _validate_option(self, option, val):
self._validate_single_char(option, val)
elif option in ("attributes"):
self._validate_attributes(option, val)
elif option in ("align"):
self._validate_align(val)
elif option in ("valign"):
self._validate_valign(val)

def _validate_field_names(self, val):
# Check for appropriate length
Expand Down Expand Up @@ -399,7 +409,7 @@ def field_names(self, val):
if old_name not in self._align:
self._align.pop(old_name)
else:
self.align = "c"
self.align = self._default_align
if self._valign and old_names:
for old_name, new_name in zip(old_names, val):
self._valign[new_name] = self._valign[old_name]
Expand All @@ -423,7 +433,7 @@ def align(self, val):
self._align = {}
elif val is None or (isinstance(val, dict) and len(val) is 0):
for field in self._field_names:
self._align[field] = "c"
self._align[field] = self._default_align
else:
self._validate_align(val)
for field in self._field_names:
Expand Down Expand Up @@ -857,7 +867,7 @@ def oldsortslice(self, val):
def _get_options(self, kwargs):

options = {}
for option in self._options:
for option in PrettyTable.OPTIONS:
if option in kwargs:
self._validate_option(option, kwargs[option])
options[option] = kwargs[option]
Expand Down Expand Up @@ -958,7 +968,7 @@ def del_row(self, row_index):
raise Exception("Cant delete row at index %d, table only has %d rows!" % (row_index, len(self._rows)))
del self._rows[row_index]

def add_column(self, fieldname, column, align="c", valign="t"):
def add_column(self, fieldname, column, align=None, valign="t"):

"""Add a column to the table.

Expand All @@ -971,7 +981,11 @@ def add_column(self, fieldname, column, align="c", valign="t"):
valign - desired vertical alignment for new columns - "t" for top, "m" for middle and "b" for bottom"""

if len(self._rows) in (0, len(column)):
self._validate_align(align)
if align is None:
align = self._default_align
else:
self._validate_align(align)

self._validate_valign(valign)
self._field_names.append(fieldname)
self._align[fieldname] = align
Expand Down
15 changes: 15 additions & 0 deletions tests/test_prettytable.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,5 +727,20 @@ def testBordered(self):
""".strip())


class InitialOptionsPreservationTest(unittest.TestCase):
def setUp(self):
self.x = PrettyTable(align='l', header=False, padding_width=0)
self.x.add_row(["abc", "def", "ghi"])
self.x.add_row("jkl")

def testAlign(self):
result = self.x.get_string()
self.assertEqual(result.strip(), """
+---+---+---+
|abc|def|ghi|
|j |k |l |
+---+---+---+
""".strip())

if __name__ == "__main__":
unittest.main()