Skip to content

Commit 7de8e51

Browse files
committed
Do not fail if CSV contains non-UTF mojibake
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
1 parent ad6d337 commit 7de8e51

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/attributecode/transform.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ def read_csv_rows(location):
258258
"""
259259
Yield rows (as a list of values) from a CSV file at `location`.
260260
"""
261-
with io.open(location, encoding='utf-8') as csvfile:
261+
# note: Excel can produce unreadable UTF files
262+
with io.open(location, encoding='utf-8', errors='replace') as csvfile:
262263
reader = csv.reader(csvfile)
263264
for row in reader:
264265
yield row

tests/test_transform.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf8 -*-
3+
4+
# ============================================================================
5+
# Copyright (c) 2014-2017 nexB Inc. http://www.nexb.com/ - All rights reserved.
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
# ============================================================================
16+
17+
from __future__ import absolute_import
18+
from __future__ import print_function
19+
from __future__ import unicode_literals
20+
21+
import unittest
22+
23+
from attributecode import transform
24+
25+
from testing_utils import get_test_loc
26+
27+
28+
class TransformTest(unittest.TestCase):
29+
30+
def test_read_csv_rows_can_read_invalid_utf8(self):
31+
test_file = get_test_loc('test_transform/mojibake.csv')
32+
list(transform.read_csv_rows(test_file))

tests/testdata/test_transform/mojibake.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Action Item Ref# , Inventory Ref# ,Product / Subsystem,Resource Path,Resource Name,Owner,Component,Version,License Category,License Name(s),License Expression,Copyright,Attribution,Redistribution,Modified,Internal Use Only,Auditor Notes,Code Download URL,License Reference,Detected License Expression,Resource Type,Resource Size,Resource SHA1,Resource File Type,Language,about_file,notice_text_file,90160,Mobile / iosapp,/iosapp/Pods/NUIParse,NUIParse,,NUIParse,v 1.3,Permissive,BSD-3-Clause,bsd-new,"Copyright (c) 2011, Thomas Cook",x,,,,"Per the .markdown file, I've used ""Copyright (c) 2011, Thomas Davie"" as the top-level copyright. LICENSE has a Thomas Davie copyright, while a number of the other files have this: Copyright 2011 In The Beginning... All rights reserved. Some have a 2012 date for the ""In The Beginningƒ¿½"" copyright. 2 files have ""Copyright (c) 2014 Ignition Soft."" Version found in /iosapp/Podfile.lock",,,,directory,0,,,,/about_files/iosapp/Pods/NUIParse/,

0 commit comments

Comments
 (0)