summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKane Blueriver <kxxoling@gmail.com>2015-04-30 15:27:55 +0800
committerKane Blueriver <kxxoling@gmail.com>2015-04-30 15:27:55 +0800
commit557a0494101ad8fad8f8ac1ed60a20cb1042b7c0 (patch)
tree25c1d5c78b76d284e6b9a1dea7a964b25e1976f5
parentacb36783bac0cb9b36de37e12426de6e307ba276 (diff)
parentc998afc75732476fa5c6b46f5995ff075487b14c (diff)
downloadpython-prettytable-ptable-557a0494101ad8fad8f8ac1ed60a20cb1042b7c0.tar.gz
Merge branch 'feature/split-prettytable-module' into develop
-rw-r--r--MANIFEST.in2
-rw-r--r--prettytable/__init__.py37
-rw-r--r--prettytable/_compact.py33
-rw-r--r--prettytable/cli.py0
-rw-r--r--prettytable/factory.py143
-rw-r--r--prettytable/prettytable.py (renamed from prettytable.py)259
-rw-r--r--test_prettytable.py (renamed from prettytable_test.py)62
7 files changed, 273 insertions, 263 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 9eae6da..581d751 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
include COPYING
include CHANGELOG
include README.rst
-include prettytable_test.py
+include test_prettytable.py
diff --git a/prettytable/__init__.py b/prettytable/__init__.py
new file mode 100644
index 0000000..87182a8
--- /dev/null
+++ b/prettytable/__init__.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2009-2014, Luke Maurits <luke@maurits.id.au>
+# All rights reserved.
+# With contributions from:
+# * Chris Clark
+# * Klein Stephane
+# * John Filleau
+# PTable forked from original Google Code page in 2015.4, and is maintained
+# by Kane Blueriver <kxxoling@gmail.com>.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+__version__ = "trunk"
+
+from .prettytable import PrettyTable
+from .prettytable import ALL, HEADER, MSWORD_FRIENDLY, NONE
+from .factory import from_csv, from_db_cursor, from_html, from_html_one
diff --git a/prettytable/_compact.py b/prettytable/_compact.py
new file mode 100644
index 0000000..9b070c2
--- /dev/null
+++ b/prettytable/_compact.py
@@ -0,0 +1,33 @@
+import sys
+
+
+py3k = sys.version_info[0] >= 3
+
+if py3k:
+ str_types = (str)
+ unicode_ = str
+ basestring_ = str
+ itermap = map
+ iterzip = zip
+ uni_chr = chr
+ from html.parser import HTMLParser
+ import io as StringIO
+else:
+ unicode_ = unicode
+ basestring_ = basestring
+ str_types = (unicode, str)
+ import itertools
+ itermap = itertools.imap
+ iterzip = itertools.izip
+ uni_chr = unichr
+ from HTMLParser import HTMLParser
+ import StringIO
+
+HTMLParser, StringIO
+
+
+if py3k and sys.version_info[1] >= 2:
+ from html import escape
+else:
+ from cgi import escape
+escape \ No newline at end of file
diff --git a/prettytable/cli.py b/prettytable/cli.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/prettytable/cli.py
diff --git a/prettytable/factory.py b/prettytable/factory.py
new file mode 100644
index 0000000..83374e7
--- /dev/null
+++ b/prettytable/factory.py
@@ -0,0 +1,143 @@
+"""
+Table factories
+"""
+import csv
+from .prettytable import PrettyTable
+from ._compact import py3k, HTMLParser
+
+
+def from_csv(fp, field_names=None, **kwargs):
+ fmtparams = {}
+ for param in ["delimiter", "doublequote", "escapechar", "lineterminator",
+ "quotechar", "quoting", "skipinitialspace", "strict"]:
+ if param in kwargs:
+ fmtparams[param] = kwargs.pop(param)
+ if fmtparams:
+ reader = csv.reader(fp, **fmtparams)
+ else:
+ dialect = csv.Sniffer().sniff(fp.read(1024))
+ fp.seek(0)
+ reader = csv.reader(fp, dialect)
+
+ table = PrettyTable(**kwargs)
+ if field_names:
+ table.field_names = field_names
+ else:
+ if py3k:
+ table.field_names = [x.strip() for x in next(reader)]
+ else:
+ table.field_names = [x.strip() for x in reader.next()]
+
+ for row in reader:
+ table.add_row([x.strip() for x in row])
+
+ return table
+
+
+def from_db_cursor(cursor, **kwargs):
+ if cursor.description:
+ table = PrettyTable(**kwargs)
+ table.field_names = [col[0] for col in cursor.description]
+ for row in cursor.fetchall():
+ table.add_row(row)
+ return table
+
+
+class TableHandler(HTMLParser):
+ def __init__(self, **kwargs):
+ HTMLParser.__init__(self)
+ self.kwargs = kwargs
+ self.tables = []
+ self.last_row = []
+ self.rows = []
+ self.max_row_width = 0
+ self.active = None
+ self.last_content = ""
+ self.is_last_row_header = False
+ self.colspan = 0
+
+ def handle_starttag(self, tag, attrs):
+ self.active = tag
+ if tag == "th":
+ self.is_last_row_header = True
+ for (key, value) in attrs:
+ if key == "colspan":
+ self.colspan = int(value)
+
+ def handle_endtag(self, tag):
+ if tag in ["th", "td"]:
+ stripped_content = self.last_content.strip()
+ self.last_row.append(stripped_content)
+ if self.colspan:
+ for i in range(1, self.colspan):
+ self.last_row.append("")
+ self.colspan = 0
+
+ if tag == "tr":
+ self.rows.append(
+ (self.last_row, self.is_last_row_header))
+ self.max_row_width = max(self.max_row_width, len(self.last_row))
+ self.last_row = []
+ self.is_last_row_header = False
+ if tag == "table":
+ table = self.generate_table(self.rows)
+ self.tables.append(table)
+ self.rows = []
+ self.last_content = " "
+ self.active = None
+
+
+ def handle_data(self, data):
+ self.last_content += data
+
+ def generate_table(self, rows):
+ """
+ Generates from a list of rows a PrettyTable object.
+ """
+ table = PrettyTable(**self.kwargs)
+ for row in self.rows:
+ if len(row[0]) < self.max_row_width:
+ appends = self.max_row_width - len(row[0])
+ for i in range(1, appends):
+ row[0].append("-")
+
+ if row[1] == True:
+ self.make_fields_unique(row[0])
+ table.field_names = row[0]
+ else:
+ table.add_row(row[0])
+ return table
+
+ def make_fields_unique(self, fields):
+ """
+ iterates over the row and make each field unique
+ """
+ for i in range(0, len(fields)):
+ for j in range(i + 1, len(fields)):
+ if fields[i] == fields[j]:
+ fields[j] += "'"
+
+
+def from_html(html_code, **kwargs):
+ """
+ Generates a list of PrettyTables from a string of HTML code. Each <table> in
+ the HTML becomes one PrettyTable object.
+ """
+
+ parser = TableHandler(**kwargs)
+ parser.feed(html_code)
+ return parser.tables
+
+
+def from_html_one(html_code, **kwargs):
+ """
+ Generates a PrettyTables from a string of HTML code which contains only a
+ single <table>
+ """
+
+ tables = from_html(html_code, **kwargs)
+ try:
+ assert len(tables) == 1
+ except AssertionError:
+ raise Exception("More than one <table> in provided HTML code! Use from_html instead.")
+ return tables[0]
diff --git a/prettytable.py b/prettytable/prettytable.py
index fee2148..3a42a7f 100644
--- a/prettytable.py
+++ b/prettytable/prettytable.py
@@ -1,65 +1,14 @@
#!/usr/bin/env python
-#
-# Copyright (c) 2009-2014, Luke Maurits <luke@maurits.id.au>
-# All rights reserved.
-# With contributions from:
-# * Chris Clark
-# * Klein Stephane
-# * John Filleau
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * The name of the author may not be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-
-__version__ = "trunk"
-
import copy
-import csv
-import itertools
import math
import random
import re
-import sys
import textwrap
import unicodedata
+from _compact import py3k, itermap, uni_chr, escape
+from _compact import str_types
+from _compact import unicode_, basestring_
-py3k = sys.version_info[0] >= 3
-if py3k:
- unicode = str
- basestring = str
- itermap = map
- iterzip = zip
- uni_chr = chr
- from html.parser import HTMLParser
-else:
- itermap = itertools.imap
- iterzip = itertools.izip
- uni_chr = unichr
- from HTMLParser import HTMLParser
-
-if py3k and sys.version_info[1] >= 2:
- from html import escape
-else:
- from cgi import escape
# hrule styles
FRAME = 0
@@ -201,10 +150,10 @@ class PrettyTable(object):
self._attributes = kwargs["attributes"] or {}
def _unicode(self, value):
- if not isinstance(value, basestring):
+ if not isinstance(value, basestring_):
value = str(value)
- if not isinstance(value, unicode):
- value = unicode(value, self.encoding, "strict")
+ if not isinstance(value, unicode_):
+ value = unicode_(value, self.encoding, "strict")
return value
def _justify(self, text, width, align):
@@ -362,7 +311,7 @@ class PrettyTable(object):
if val == "":
return
try:
- assert type(val) in (str, unicode)
+ assert type(val) in str_types
assert val.isdigit()
except AssertionError:
raise Exception("Invalid value for %s! Must be an integer format string." % name)
@@ -372,7 +321,7 @@ class PrettyTable(object):
return
try:
val = val.rsplit('f')[0]
- assert type(val) in (str, unicode)
+ assert type(val) in str_types
assert "." in val
bits = val.split(".")
assert len(bits) <= 2
@@ -1595,195 +1544,3 @@ def _char_block_width(char):
def _str_block_width(val):
return sum(itermap(_char_block_width, itermap(ord, _re.sub("", val))))
-
-##############################
-# TABLE FACTORIES #
-##############################
-
-def from_csv(fp, field_names=None, **kwargs):
- fmtparams = {}
- for param in ["delimiter", "doublequote", "escapechar", "lineterminator",
- "quotechar", "quoting", "skipinitialspace", "strict"]:
- if param in kwargs:
- fmtparams[param] = kwargs.pop(param)
- if fmtparams:
- reader = csv.reader(fp, **fmtparams)
- else:
- dialect = csv.Sniffer().sniff(fp.read(1024))
- fp.seek(0)
- reader = csv.reader(fp, dialect)
-
- table = PrettyTable(**kwargs)
- if field_names:
- table.field_names = field_names
- else:
- if py3k:
- table.field_names = [x.strip() for x in next(reader)]
- else:
- table.field_names = [x.strip() for x in reader.next()]
-
- for row in reader:
- table.add_row([x.strip() for x in row])
-
- return table
-
-
-def from_db_cursor(cursor, **kwargs):
- if cursor.description:
- table = PrettyTable(**kwargs)
- table.field_names = [col[0] for col in cursor.description]
- for row in cursor.fetchall():
- table.add_row(row)
- return table
-
-
-class TableHandler(HTMLParser):
- def __init__(self, **kwargs):
- HTMLParser.__init__(self)
- self.kwargs = kwargs
- self.tables = []
- self.last_row = []
- self.rows = []
- self.max_row_width = 0
- self.active = None
- self.last_content = ""
- self.is_last_row_header = False
- self.colspan = 0
-
- def handle_starttag(self, tag, attrs):
- self.active = tag
- if tag == "th":
- self.is_last_row_header = True
- for (key, value) in attrs:
- if key == "colspan":
- self.colspan = int(value)
-
-
- def handle_endtag(self, tag):
- if tag in ["th", "td"]:
- stripped_content = self.last_content.strip()
- self.last_row.append(stripped_content)
- if self.colspan:
- for i in range(1, self.colspan):
- self.last_row.append("")
- self.colspan = 0
-
- if tag == "tr":
- self.rows.append(
- (self.last_row, self.is_last_row_header))
- self.max_row_width = max(self.max_row_width, len(self.last_row))
- self.last_row = []
- self.is_last_row_header = False
- if tag == "table":
- table = self.generate_table(self.rows)
- self.tables.append(table)
- self.rows = []
- self.last_content = " "
- self.active = None
-
-
- def handle_data(self, data):
- self.last_content += data
-
- def generate_table(self, rows):
- """
- Generates from a list of rows a PrettyTable object.
- """
- table = PrettyTable(**self.kwargs)
- for row in self.rows:
- if len(row[0]) < self.max_row_width:
- appends = self.max_row_width - len(row[0])
- for i in range(1, appends):
- row[0].append("-")
-
- if row[1] == True:
- self.make_fields_unique(row[0])
- table.field_names = row[0]
- else:
- table.add_row(row[0])
- return table
-
- def make_fields_unique(self, fields):
- """
- iterates over the row and make each field unique
- """
- for i in range(0, len(fields)):
- for j in range(i + 1, len(fields)):
- if fields[i] == fields[j]:
- fields[j] += "'"
-
-
-def from_html(html_code, **kwargs):
- """
- Generates a list of PrettyTables from a string of HTML code. Each <table> in
- the HTML becomes one PrettyTable object.
- """
-
- parser = TableHandler(**kwargs)
- parser.feed(html_code)
- return parser.tables
-
-
-def from_html_one(html_code, **kwargs):
- """
- Generates a PrettyTables from a string of HTML code which contains only a
- single <table>
- """
-
- tables = from_html(html_code, **kwargs)
- try:
- assert len(tables) == 1
- except AssertionError:
- raise Exception("More than one <table> in provided HTML code! Use from_html instead.")
- return tables[0]
-
-
-##############################
-# MAIN (TEST FUNCTION) #
-##############################
-
-def main():
- print("Generated using setters:")
- x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])
- x.title = "Australian capital cities"
- x.sortby = "Population"
- x.reversesort = True
- x.int_format["Area"] = "04"
- x.float_format = "6.1"
- x.align["City name"] = "l" # Left align city names
- x.add_row(["Adelaide", 1295, 1158259, 600.5])
- x.add_row(["Brisbane", 5905, 1857594, 1146.4])
- x.add_row(["Darwin", 112, 120900, 1714.7])
- x.add_row(["Hobart", 1357, 205556, 619.5])
- x.add_row(["Sydney", 2058, 4336374, 1214.8])
- x.add_row(["Melbourne", 1566, 3806092, 646.9])
- x.add_row(["Perth", 5386, 1554769, 869.4])
- print(x)
-
- print
-
- print("Generated using constructor arguments:")
-
- y = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"],
- title="Australian capital cities",
- sortby="Population",
- reversesort=True,
- int_format="04",
- float_format="6.1",
- max_width=12,
- min_width=4,
- align="c",
- valign="t")
- y.align["City name"] = "l" # Left align city names
- y.add_row(["Adelaide", 1295, 1158259, 600.5])
- y.add_row(["Brisbane", 5905, 1857594, 1146.4])
- y.add_row(["Darwin", 112, 120900, 1714.7])
- y.add_row(["Hobart", 1357, 205556, 619.5])
- y.add_row(["Sydney", 2058, 4336374, 1214.8])
- y.add_row(["Melbourne", 1566, 3806092, 646.9])
- y.add_row(["Perth", 5386, 1554769, 869.4])
- print(y)
-
-
-if __name__ == "__main__":
- main()
diff --git a/prettytable_test.py b/test_prettytable.py
index 1552505..b337088 100644
--- a/prettytable_test.py
+++ b/test_prettytable.py
@@ -1,21 +1,17 @@
#!/usr/bin/env python
# coding=UTF-8
-from prettytable import *
+from prettytable import PrettyTable
+from prettytable import ALL, HEADER, MSWORD_FRIENDLY, NONE
+from prettytable import from_csv, from_db_cursor, from_html, from_html_one
-import sys
-
-py3k = sys.version_info[0] >= 3
+from prettytable._compact import StringIO
try:
import sqlite3
-
_have_sqlite = True
except ImportError:
_have_sqlite = False
-if py3k:
- import io as StringIO
-else:
- import StringIO
+
from math import pi, e, sqrt
import unittest
@@ -92,6 +88,7 @@ class BuildEquivelanceTest(unittest.TestCase):
# self.x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]
# self.x.get_string()
+
class CityDataTest(unittest.TestCase):
"""Just build the Australian capital city data example table."""
@@ -578,12 +575,55 @@ class HtmlConstructorTest(CityDataTest):
class PrintEnglishTest(CityDataTest):
- def testPrint(self):
+ def setUp(self):
+ x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])
+ x.title = "Australian capital cities"
+ x.sortby = "Population"
+ x.reversesort = True
+ x.int_format["Area"] = "04"
+ x.float_format = "6.1"
+ x.align["City name"] = "l" # Left align city names
+ x.add_row(["Adelaide", 1295, 1158259, 600.5])
+ x.add_row(["Brisbane", 5905, 1857594, 1146.4])
+ x.add_row(["Darwin", 112, 120900, 1714.7])
+ x.add_row(["Hobart", 1357, 205556, 619.5])
+ x.add_row(["Sydney", 2058, 4336374, 1214.8])
+ x.add_row(["Melbourne", 1566, 3806092, 646.9])
+ x.add_row(["Perth", 5386, 1554769, 869.4])
+ self.x = x
+
+ y = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"],
+ title="Australian capital cities",
+ sortby="Population",
+ reversesort=True,
+ int_format="04",
+ float_format="6.1",
+ max_width=12,
+ min_width=4,
+ align="c",
+ valign="t")
+ y.align["City name"] = "l" # Left align city names
+ y.add_row(["Adelaide", 1295, 1158259, 600.5])
+ y.add_row(["Brisbane", 5905, 1857594, 1146.4])
+ y.add_row(["Darwin", 112, 120900, 1714.7])
+ y.add_row(["Hobart", 1357, 205556, 619.5])
+ y.add_row(["Sydney", 2058, 4336374, 1214.8])
+ y.add_row(["Melbourne", 1566, 3806092, 646.9])
+ y.add_row(["Perth", 5386, 1554769, 869.4])
+ self.y = y
+
+ def test_h_print(self):
print()
+ print("Generated using setters:")
print(self.x)
+ def test_v_print(self):
+ print()
+ print("Generated using constructor arguments:")
+ print(self.y)
+
-class PrintJapanestTest(unittest.TestCase):
+class PrintJapaneseTest(unittest.TestCase):
def setUp(self):
self.x = PrettyTable(["Kanji", "Hiragana", "English"])
self.x.add_row(["神戸", "こうべ", "Kobe"])