Problème d'encoding avec la locale C
Luthaf opened this issue · 21 comments
J'ai cette stacktrace sur l'instance que je tente de déployer :
[ERROR] -- 2015-04-29 21:48:13,759 -- base : Internal Server Error: /fr/songs/la-compagnie-creole/la-machine-a-danser/
Traceback (most recent call last):
File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/core/handlers/base.py", line 111, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/base.py", line 87, in dispatch
return handler(request, *args, **kwargs)
File "/home/patanet/pyvenv/lib/python3.4/site-packages/django/views/generic/detail.py", line 115, in get
context = self.get_context_data(object=self.object)
File "./generator/views/songs.py", line 70, in get_context_data
context['content'] = _read_song(context['song'])
File "./generator/views/songs.py", line 55, in _read_song
return parse_song(path)
File "./generator/songs.py", line 25, in parse_song
return fd.read()
File "/usr/local/lib/python3.4/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 62: ordinal not in range(128)
Je vais regarder d'où ça peut venir, et si je la reproduis en local, mais si vous avez une idée je suis preneur. Ping @paternal pour les erreurs d'encoding =)
Non reproductible en local, la seule différence porte sur la locale du système : C
sur le serveur, fr_FR.UTF-8
chez moi. En changeant la locale du serveur, tout refonctionne.
Ca correspond à cela vraisemblablement : https://bugs.python.org/issue19846
Youpi, un bug python ... Bon, je m'en vais documenter ça, étant donné qu'il s'agit d'une erreur peut courante et facile à corriger.
Est-il possible de détecter la locale lors du démarrage ? (et d'afficher un message d'erreur avec correction si la locale est "C").
Ça peut se faire aussi en effet.
Yo! J'ai essayé de jeter un œil à ça. J'ai suivi la doc (avec python 3.4.2) pour installer et lancer l'application, mais j'obtiens l'erreur suivante :
$ ./manage.py migrate
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/core/management/__init__.py", line 312, in execute
django.setup()
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/django/apps/config.py", line 198, in import_models
self.models_module = import_module(models_module_name)
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1129, in _exec
File "<frozen importlib._bootstrap>", line 1471, in exec_module
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "/home/louis/projets/patacrep/virtualenv.net/lib/python3.4/site-packages/background_task/models.py", line 8, in <module>
from StringIO import StringIO
ImportError: No module named 'StringIO'
Que faire (puisque StringIO
ne fait pas partie de python 3.4) ?
Il faut se baser sur la branche python3, qui n'est pas encore mergée dans master.
Je suis bien dans cette branche, à jour, avec python 3. Pas le temps d'enquêter davantage ce soir. Je regarde plus tard dans un virtualenv neuf, avec un dépôt neuf.
Vous êtes sûrs que background task est compatible python 3 ? Rien n'est précisé sur le dépôt ou pypi, et le fichier models.py
contient l'import à StringIO
, qui n'existe plus sous Python3.
La question maintenant, c'est : Pourquoi ça marche chez vous et pas chez moi ? La suite au prochain épisode…
Cf: #100 (comment)
(apparemment, ça n'a pas encore été mergé...)
pip install git+https://github.com/Luthaf/django-background-task.git
La question maintenant, c'est : Pourquoi ça marche chez vous et pas chez moi ? La suite au prochain épisode…
My bad ... J'étais persuadé d'avoir mis à jour le Requirement.txt
Merci pour les réponses. Je ré-essaye tout ça à l'occasion.
Bon, j'ai un problème : chez moi ça marche.
$ LANG=C ./manage.py runserver
/home/louis/projets/patacrep/virtualenv/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
return f(*args, **kwds)
/home/louis/projets/patacrep/virtualenv/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
return f(*args, **kwds)
Performing system checks...
System check identified no issues (0 silenced).
May 03, 2015 - 19:39:31
Django version 1.8.1, using settings 'patanet.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Et a priori, tous les paquets sont à jour.
$ python --version
Python 3.4.1
$ pip freeze
Babel==1.3
Django==1.8.1
Jinja2==2.7.3
MarkupSafe==0.23
Pillow==2.8.1
Pygments==2.0.2
Sphinx==1.3.1
Unidecode==0.04.17
alabaster==0.7.3
argparse==1.2.1
astroid==1.3.6
cffi==0.9.2
chardet==2.2.1
django-background-task==0.1.8
django-simple-captcha==0.4.5
docutils==0.12
ipdb==0.8
ipython==3.1.0
jsonfield==1.0.3
lesscpy==0.10.2
logilab-common==0.63.2
patacrep==4.0.0
ply==3.4
pycparser==2.12
pygit2==0.21.0
pylint==1.4.3
pytz==2015.2
six==1.9.0
snowballstemmer==1.2.0
sphinx-rtd-theme==0.1.7
Une idée ?
Le serveur se lance sans problème, mais c'est en accédant à une chanson que ça plante. Donc si tu as importé des chansons, va sur la page des paroles de cette chanson.
Je ne sais pas d'ou vient le problème, mais en diagnostiquant, j'ai l'impression d'avoir trouvé par hasard un moyen de contourner le problème.
diff --git a/generator/songs.py b/generator/songs.py
index 772a496..d89573e 100644
--- a/generator/songs.py
+++ b/generator/songs.py
@@ -18,8 +18,10 @@
Functions for song file (.sg) rendering.
"""
+import codecs
+
def parse_song(filename):
"""Parse song 'filename', and return the corresponding HTML code."""
# TODO
- with open(filename) as fd:
+ with codecs.open(filename) as fd:
return fd.read()
Dites moi ce que vous en pensez…
Selon http://programmers.stackexchange.com/a/168645,
open(filename, encoding='utf-8')
devrait aussi fonctionner.
L'une ou l'autre solution me convient totalement =)
Pendant le développement, je pense que c'est bien de cherche à corriger cela. En production, ça pourra être bien d'utiliser l'option errors="replace"
de open(), pour que de telles erreurs, qu'elles viennent de l'utilisateur ou des développeurs, ne renvoient pas une erreur moche à l'utilisateur.
Le mauvais côté, c'est qu'on ignore les erreurs, et qu'on ne va plus les corriger…
Je pense qu'en production il faut éviter d'afficher les erreurs, mais les reporter aux dev (dans ce cas, afficher une page "Erreur 500" et avoir des logs quelque part qui indiquent le problème).
Sinon on risque des pertes de données (des caractères seront remplacés par '?' et le débogage deviendra impossible)
Je n'ai jamais eu ce problème, mais la lecture étant désormais effectuée par patacrep, je pense qu'on peut clore cette issue (mais j'ai quand même un problème d'encodage qui traîne)