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
32 changes: 31 additions & 1 deletion rows/plugins/plugin_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,20 @@ def import_from_csv(filename_or_fobj, encoding='utf-8', dialect=None,
`open(filename, mode='rb')`.
'''

error_msg = '''Error importing from CSV. Details:
Filename: {filename}
File object: {fobj}
Dialect (guessed?): {dialect} ({guessed})
Encoding: {encoding}
Sample size: {sample_size} bytes
Reason: {exc}
'''

filename, fobj = get_filename_and_fobj(filename_or_fobj, mode='rb')

guessed = False
if dialect is None:
guessed = True
cursor = fobj.tell()
dialect = discover_dialect(fobj.read(sample_size), encoding)
fobj.seek(cursor)
Expand All @@ -68,7 +79,26 @@ def import_from_csv(filename_or_fobj, encoding='utf-8', dialect=None,
meta = {'imported_from': 'csv',
'filename': filename,
'encoding': encoding,}
return create_table(reader, meta=meta, *args, **kwargs)
try:
try:
table = create_table(reader, meta=meta, *args, **kwargs)
except ValueError as e:
if guessed:
dialect = unicodecsv.excel
fobj.seek(cursor)
reader = unicodecsv.reader(fobj, encoding=encoding,
dialect=dialect)
table = create_table(reader, meta=meta, *args, **kwargs)
else:
raise
except Exception as e:
name = 'Excel' if dialect is unicodecsv.excel else dialect._name
error = error_msg.format(filename=filename, fobj=fobj,
dialect=name, guessed=guessed, encoding=encoding,
sample_size=sample_size, exc=e)
raise unicodecsv.Error(error) from e

return table


def export_to_csv(table, filename_or_fobj=None, encoding='utf-8',
Expand Down
22 changes: 22 additions & 0 deletions tests/tests_plugin_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,25 @@ def test_export_to_csv_accepts_dialect(self):
result_1 = rows.export_to_csv(utils.table, dialect=csv.excel_tab)
result_2 = rows.export_to_csv(utils.table, dialect=csv.excel)
self.assertEqual(result_1.replace(b'\t', b','), result_2)

def test_issue_218_revert_guess(self):

err = b"""problematic_text,cool_number\n,42\n"Problematic text with\
commas, ""quotes"" and a cool number: 4,2", 84"""

csv_input = BytesIO(err)
table = rows.import_from_csv(csv_input, dialect='excel')
as_list = list(table)
csv_input = BytesIO(err)
table = rows.import_from_csv(csv_input)
self.assertEqual(as_list, list(table))

def test_issue_218_better_msg(self):
err = b"""problematic_text,cool_number\n,42\n"Problematic text with\
commas, ""quotes"" and a cool number: 4,2", 84"""

tricky_table = err * 1000 + bytes(range(256))
self.assertRaises(csv.Error, rows.import_from_csv, BytesIO(tricky_table))

with self.assertRaisesRegex(csv.Error, 'Details'):
tricked = rows.import_from_csv(BytesIO(tricky_table), encoding='utf-8')