@@ -2469,26 +2469,7 @@ def _next_line(self):
2469
2469
next (self .data )
2470
2470
2471
2471
while True :
2472
- try :
2473
- orig_line = next (self .data )
2474
- except csv .Error as e :
2475
- msg = str (e )
2476
-
2477
- if 'NULL byte' in str (e ):
2478
- msg = ('NULL byte detected. This byte '
2479
- 'cannot be processed in Python\' s '
2480
- 'native csv library at the moment, '
2481
- 'so please pass in engine=\' c\' instead' )
2482
-
2483
- if self .skipfooter > 0 :
2484
- reason = ('Error could possibly be due to '
2485
- 'parsing errors in the skipped footer rows '
2486
- '(the skipfooter keyword is only applied '
2487
- 'after Python\' s csv library has parsed '
2488
- 'all rows).' )
2489
- msg += '. ' + reason
2490
-
2491
- raise csv .Error (msg )
2472
+ orig_line = self ._next_iter_line (self .data )
2492
2473
line = self ._check_comments ([orig_line ])[0 ]
2493
2474
self .pos += 1
2494
2475
if (not self .skip_blank_lines and
@@ -2510,6 +2491,45 @@ def _next_line(self):
2510
2491
self .buf .append (line )
2511
2492
return line
2512
2493
2494
+ def _next_iter_line (self , source , ** kwargs ):
2495
+ """
2496
+ Wrapper around iterating through a CSV source.
2497
+
2498
+ When a CSV error is raised, we check for specific
2499
+ error messages that allow us to customize the
2500
+ error message displayed to the user.
2501
+
2502
+ Parameters
2503
+ ----------
2504
+ source : The CSV source through which to iterate.
2505
+ kwargs : Keyword arguments used to customize the error message.
2506
+ """
2507
+
2508
+ try :
2509
+ return next (source )
2510
+ except csv .Error as e :
2511
+ msg = str (e )
2512
+
2513
+ if 'NULL byte' in msg :
2514
+ msg = ('NULL byte detected. This byte '
2515
+ 'cannot be processed in Python\' s '
2516
+ 'native csv library at the moment, '
2517
+ 'so please pass in engine=\' c\' instead' )
2518
+ elif 'newline inside string' in msg :
2519
+ msg = ('EOF inside string starting with '
2520
+ 'line ' + str (kwargs ['row_num' ]))
2521
+ raise Exception (msg )
2522
+
2523
+ if self .skipfooter > 0 :
2524
+ reason = ('Error could possibly be due to '
2525
+ 'parsing errors in the skipped footer rows '
2526
+ '(the skipfooter keyword is only applied '
2527
+ 'after Python\' s csv library has parsed '
2528
+ 'all rows).' )
2529
+ msg += '. ' + reason
2530
+
2531
+ raise csv .Error (msg )
2532
+
2513
2533
def _check_comments (self , lines ):
2514
2534
if self .comment is None :
2515
2535
return lines
@@ -2730,17 +2750,13 @@ def _get_lines(self, rows=None):
2730
2750
lines .extend (new_rows )
2731
2751
else :
2732
2752
rows = 0
2753
+
2733
2754
while True :
2734
- try :
2735
- new_rows .append (next (source ))
2736
- rows += 1
2737
- except csv .Error as inst :
2738
- if 'newline inside string' in str (inst ):
2739
- row_num = str (self .pos + rows )
2740
- msg = ('EOF inside string starting with '
2741
- 'line ' + row_num )
2742
- raise Exception (msg )
2743
- raise
2755
+ new_row = self ._next_iter_line (
2756
+ source , row_num = self .pos + rows )
2757
+ new_rows .append (new_row )
2758
+ rows += 1
2759
+
2744
2760
except StopIteration :
2745
2761
if self .skiprows :
2746
2762
new_rows = [row for i , row in enumerate (new_rows )
0 commit comments