Project

General

Profile

Development #41612

csvdatasource: ne pas faire .splitlines() sur le contenu du CSV

Added by Benjamin Dauvergne 8 months ago. Updated about 2 months ago.

Status:
Rejeté
Priority:
Normal
Target version:
-
Start date:
10 Apr 2020
Due date:
% Done:

0%

Patch proposed:
Yes
Planning:
No

Description

Les fichiers CSV contenant des sauts de ligne les perdent (tester par exemple :

id,text,comment
1,a,"un
long
texte" 
2,a,b

parce que le fichier est parsé de cette manière :

            reader = csv.reader(content.splitlines(), **self.dialect_options)

et str.splitlines supprime les sauts de ligne de chaque ligne (contrairement à open(..).readlines()).

test.csv View (42 Bytes) Benjamin Dauvergne, 10 Apr 2020 05:10 PM

0001-csvdatasource-keep-inline-newlines-when-parsing-CSV-.patch View (2.55 KB) Benjamin Dauvergne, 10 Apr 2020 05:27 PM

0001-csvdatasource-keep-inline-newlines-when-parsing-CSV-.patch View (2.37 KB) Benjamin Dauvergne, 11 Apr 2020 01:43 PM

0002-csvdatasource-backports-fix-on-csv.Sniffer-41612.patch View (7.07 KB) Benjamin Dauvergne, 11 Apr 2020 01:43 PM

History

#1 Updated by Benjamin Dauvergne 8 months ago

  • Tracker changed from Support to Bug

#3 Updated by Benjamin Dauvergne 8 months ago

  • Assignee set to Benjamin Dauvergne

#4 Updated by Benjamin Dauvergne 8 months ago

#5 Updated by Benjamin Dauvergne 8 months ago

  • Status changed from Solution proposée to En cours

Et donc personne n'avait jamais vu le problème parce que personne n'a réussi à faire avaler un fichier CSV avec des sauts de ligne, le sniffer en 2.7.13 n'y arrive pas (sur ma machine en 2.7.16 ça marche très bien).

https://github.com/python/cpython/blob/2.7/Misc/NEWS.d/2.7.15rc1.rst

Fixed guessing quote and delimiter in csv.Sniffer.sniff() when only the last field is quoted. Patch by Jake Davis.

#6 Updated by Benjamin Dauvergne 8 months ago

  • Status changed from En cours to Solution proposée

Bon ben voilà, en rajoutant une colonne ça passe.

#7 Updated by Benjamin Dauvergne 8 months ago

Le changement est assez minime entre 2.7.13 et 2.7.16 :

$ diff -ub /tmp/csv.py /usr/lib/python2.7/csv.py
--- /tmp/csv.py    2020-04-11 12:37:50.081188000 +0200
+++ /usr/lib/python2.7/csv.py    2019-09-04 10:19:57.000000000 +0200
@@ -217,7 +217,7 @@
         matches = []
         for restr in ('(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', # ,".*?",
                       '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\w\n"\'])(?P<space> ?)',   #  ".*?",
-                      '(?P<delim>>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)',  # ,".*?" 
+                      '(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)',   # ,".*?" 
                       '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):                            #  ".*?" (no delim, no space)
             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
             matches = regexp.findall(data)

J'ai bien envie de la backporter manuellement.

#9 Updated by Benjamin Dauvergne about 2 months ago

  • Status changed from Solution proposée to Rejeté

De toute façon ça ne marchera jamais bien, il faut un formulaire explicite de définition des paramètres du CSV, il n'existe pas d'autre moyen (Sniffer est capable de prendre les espaces pour des séparateurs sur un CSV suffisamment compliqué).

Also available in: Atom PDF