Skip to content

Commit

Permalink
Fix other functions to conform with PEP 479
Browse files Browse the repository at this point in the history
Applies the same fix that was done for iterrowslice to other functions that may receive an empty (as in headerless) table as input.
#613
  • Loading branch information
augustomen authored and juarezr committed Aug 22, 2023
1 parent c411e0f commit c285868
Show file tree
Hide file tree
Showing 47 changed files with 878 additions and 117 deletions.
5 changes: 4 additions & 1 deletion petl/io/csv_py2.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ def __iter__(self):
it = iter(self.table)

# deal with header row
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
return
if self.write_header:
writer.writerow(hdr)
# N.B., always yield header, even if we don't write it
Expand Down
17 changes: 10 additions & 7 deletions petl/io/csv_py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ def fromcsv_impl(source, **kwargs):
class CSVView(Table):

def __init__(self, source, encoding, errors, header, **csvargs):
self.source = source
self.encoding = encoding
self.errors = errors
self.csvargs = csvargs
self.header = header
self.source = source
self.encoding = encoding
self.errors = errors
self.csvargs = csvargs
self.header = header

def __iter__(self):
if self.header is not None:
yield tuple(self.header)
yield tuple(self.header)
with self.source.open('rb') as buf:
csvfile = io.TextIOWrapper(buf, encoding=self.encoding,
errors=self.errors, newline='')
Expand Down Expand Up @@ -86,7 +86,10 @@ def __iter__(self):
try:
writer = csv.writer(csvfile, **self.csvargs)
it = iter(self.table)
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
return
if self.write_header:
writer.writerow(hdr)
yield tuple(hdr)
Expand Down
33 changes: 20 additions & 13 deletions petl/io/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ def tohtml(table, source=None, encoding=None, errors='strict', caption=None,
it = iter(table)

# write header
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
hdr = []
_write_begin(f, hdr, lineterminator, caption, index_header,
truncate)

Expand Down Expand Up @@ -166,10 +169,13 @@ def __iter__(self):
it = iter(table)

# write header
hdr = next(it)
try:
hdr = next(it)
yield hdr
except StopIteration:
hdr = []
_write_begin(f, hdr, lineterminator, caption, index_header,
truncate)
yield hdr

# write body
if tr_style and callable(tr_style):
Expand All @@ -193,16 +199,17 @@ def _write_begin(f, flds, lineterminator, caption, index_header, truncate):
f.write("<table class='petl'>" + lineterminator)
if caption is not None:
f.write(('<caption>%s</caption>' % caption) + lineterminator)
f.write('<thead>' + lineterminator)
f.write('<tr>' + lineterminator)
for i, h in enumerate(flds):
if index_header:
h = '%s|%s' % (i, h)
if truncate:
h = h[:truncate]
f.write(('<th>%s</th>' % h) + lineterminator)
f.write('</tr>' + lineterminator)
f.write('</thead>' + lineterminator)
if flds:
f.write('<thead>' + lineterminator)
f.write('<tr>' + lineterminator)
for i, h in enumerate(flds):
if index_header:
h = '%s|%s' % (i, h)
if truncate:
h = h[:truncate]
f.write(('<th>%s</th>' % h) + lineterminator)
f.write('</tr>' + lineterminator)
f.write('</thead>' + lineterminator)
f.write('<tbody>' + lineterminator)


Expand Down
5 changes: 4 additions & 1 deletion petl/io/pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ def todataframe(table, index=None, exclude=None, columns=None,
"""
import pandas as pd
it = iter(table)
header = next(it)
try:
header = next(it)
except StopIteration:
header = None # Will create an Empty DataFrame
if columns is None:
columns = header
return pd.DataFrame.from_records(it, index=index, exclude=exclude,
Expand Down
10 changes: 8 additions & 2 deletions petl/io/pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ def _writepickle(table, source, mode, protocol, write_header):
source = write_source_from_arg(source, mode)
with source.open(mode) as f:
it = iter(table)
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
return
if write_header:
pickle.dump(hdr, f, protocol)
for row in it:
Expand Down Expand Up @@ -153,7 +156,10 @@ def __iter__(self):
source = write_source_from_arg(self.source)
with source.open('wb') as f:
it = iter(self.table)
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
return
if self.write_header:
pickle.dump(hdr, f, protocol)
yield tuple(hdr)
Expand Down
10 changes: 8 additions & 2 deletions petl/io/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ def _writetext(table, source, mode, encoding, errors, template, prologue,
if prologue is not None:
f.write(prologue)
it = iter(table)
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
hdr = []
flds = list(map(text_type, hdr))
for row in it:
rec = asdict(flds, row)
Expand Down Expand Up @@ -266,7 +269,10 @@ def _iterteetext(table, source, encoding, errors, template, prologue, epilogue):
if prologue is not None:
f.write(prologue)
it = iter(table)
hdr = next(it)
try:
hdr = next(it)
except StopIteration:
return
yield tuple(hdr)
flds = list(map(text_type, hdr))
for row in it:
Expand Down
15 changes: 9 additions & 6 deletions petl/io/xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,15 @@ def toxls(tbl, filename, sheet, encoding=None, style_compression=0,
else:
# handle styles
it = iter(tbl)
hdr = next(it)
flds = list(map(str, hdr))
for c, f in enumerate(flds):
ws.write(0, c, label=f)
if f not in styles or styles[f] is None:
styles[f] = xlwt.Style.default_style
try:
hdr = next(it)
flds = list(map(str, hdr))
for c, f in enumerate(flds):
ws.write(0, c, label=f)
if f not in styles or styles[f] is None:
styles[f] = xlwt.Style.default_style
except StopIteration:
pass # no header written
# convert to list for easy zipping
styles = [styles[f] for f in flds]
for r, row in enumerate(it):
Expand Down
18 changes: 12 additions & 6 deletions petl/io/xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,12 @@ def toxlsx(tbl, filename, sheet=None, write_header=True, mode="replace"):
ws = _insert_sheet_on_workbook(mode, sheet, wb)
if write_header:
it = iter(tbl)
hdr = next(it)
flds = list(map(text_type, hdr))
rows = itertools.chain([flds], it)
try:
hdr = next(it)
flds = list(map(text_type, hdr))
rows = itertools.chain([flds], it)
except StopIteration:
rows = it
else:
rows = data(tbl)
for row in rows:
Expand Down Expand Up @@ -184,9 +187,12 @@ def appendxlsx(tbl, filename, sheet=None, write_header=False):
ws = wb[str(sheet)]
if write_header:
it = iter(tbl)
hdr = next(it)
flds = list(map(text_type, hdr))
rows = itertools.chain([flds], it)
try:
hdr = next(it)
flds = list(map(text_type, hdr))
rows = itertools.chain([flds], it)
except StopIteration:
rows = it
else:
rows = data(tbl)
for row in rows:
Expand Down
2 changes: 1 addition & 1 deletion petl/test/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

def eq_(expect, actual, msg=None):
"""Test when two values from a python variable are exactly equals (==)"""
assert expect == actual, msg
assert expect == actual, msg or ('%r != %s' % (expect, actual))


def assert_almost_equal(first, second, places=None, msg=None):
Expand Down
18 changes: 18 additions & 0 deletions petl/test/io/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,21 @@ def test_tohtml_with_style():
u"</table>\n"
)
eq_(expect, actual)


def test_tohtml_headerless():
table = []

f = NamedTemporaryFile(delete=False)
tohtml(table, f.name, encoding='ascii', lineterminator='\n')

# check what it did
with io.open(f.name, mode='rt', encoding='ascii', newline='') as o:
actual = o.read()
expect = (
u"<table class='petl'>\n"
u"<tbody>\n"
u"</tbody>\n"
u"</table>\n"
)
eq_(expect, actual)
6 changes: 6 additions & 0 deletions petl/test/io/test_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def test_todataframe():
actual = todataframe(tbl)
assert expect.equals(actual)

def test_headerless():
tbl = []
expect = pd.DataFrame()
actual = todataframe(tbl)
assert expect.equals(actual)

def test_fromdataframe():
tbl = [('foo', 'bar', 'baz'),
('apples', 1, 2.5),
Expand Down
24 changes: 17 additions & 7 deletions petl/test/io/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
from petl.io.pickle import frompickle, topickle, appendpickle


def picklereader(fl):
try:
while True:
yield pickle.load(fl)
except EOFError:
pass


def test_frompickle():

f = NamedTemporaryFile(delete=False)
Expand All @@ -36,13 +44,6 @@ def test_topickle_appendpickle():
f = NamedTemporaryFile(delete=False)
topickle(table, f.name)

def picklereader(fl):
try:
while True:
yield pickle.load(fl)
except EOFError:
pass

# check what it did
with open(f.name, 'rb') as o:
actual = picklereader(o)
Expand All @@ -66,3 +67,12 @@ def picklereader(fl):
('e', 9),
('f', 1))
ieq(expect, actual)


def test_topickle_headerless():
table = []
f = NamedTemporaryFile(delete=False)
topickle(table, f.name)
expect = []
with open(f.name, 'rb') as o:
ieq(expect, picklereader(o))
15 changes: 15 additions & 0 deletions petl/test/io/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,18 @@ def test_totext_gz():
eq_(expect, actual)
finally:
o.close()


def test_totext_headerless():
table = []
f = NamedTemporaryFile(delete=False)
prologue = "-- START\n"
template = "+ {f1}\n"
epilogue = "-- END\n"
totext(table, f.name, encoding='ascii', template=template,
prologue=prologue, epilogue=epilogue)

with io.open(f.name, mode='rt', encoding='ascii', newline='') as o:
actual = o.read()
expect = prologue + epilogue
eq_(expect, actual)
11 changes: 10 additions & 1 deletion petl/test/io/test_xls.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ def test_toxls():
ieq(expect, actual)
ieq(expect, actual)

def test_toxls_headerless():
expect = []
f = NamedTemporaryFile(delete=False)
f.close()
toxls(expect, f.name, 'Sheet1')
actual = fromxls(f.name, 'Sheet1')
ieq(expect, actual)
ieq(expect, actual)

def test_toxls_date():
expect = (('foo', 'bar'),
(u'é', datetime(2012, 1, 1)),
Expand Down Expand Up @@ -128,4 +137,4 @@ def wrapper(self, *args, **kwargs):
('C', 2),
(u'é', datetime(2012, 1, 1)))
ieq(expect, tbl)
ieq(expect, tbl)
ieq(expect, tbl)
10 changes: 10 additions & 0 deletions petl/test/io/test_xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,13 @@ def test_appendxlsx_with_non_str_header(xlsx_table_with_non_str_header, xlsx_tes
appendxlsx(xlsx_table_with_non_str_header, f.name, 'Sheet1')
expect = etl.cat(xlsx_test_table, xlsx_table_with_non_str_header)
ieq(expect, actual)


def test_toxlsx_headerless():
expect = []
f = NamedTemporaryFile(delete=False)
f.close()
toxlsx(expect, f.name)
actual = fromxlsx(f.name)
ieq(expect, actual)
ieq(expect, actual)
Loading

0 comments on commit c285868

Please sign in to comment.