2015-12-13 5 views
0

Как указать кодировку при запуске скрипта python в качестве модуля?python -m <filename><encoding>?

Например, я хочу запустить my_script.py как python -m my_script -utf8. Но такого выбора нет. Вместо этого я должен предоставить my_script.py с кодировкой поверх файла. И он терпит неудачу с некоторыми пакетами python-2.7.

Рассмотрим следующий сценарий:

my_script.py:

# coding=utf-8 
from pyglet.gl import * 
  1. $ cd ~/Documents
  2. создать папку без ASCII: $ mkdir вафля
  3. $ cd вафля
  4. создать my_script.py с выше
  5. python my_script.py код - работает хорошо
  6. python -m my_script - терпит неудачу

Работа станции: Ubuntu 14.04.3 x64 + Python 2.7.6 x64 (встроенный)

Не предлагайте мне включить Python 3.4, потому что я уже сделал это и просто хочу поддерживать версии 2.7 и 3.4 Python.

Добавлено traceback.

File "my_script.py", line 22, in <module> 
    from pyglet.gl import * 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/gl/__init__.py", line 236, in <module> 
    import pyglet.window 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/__init__.py", line 1817, in <module> 
    gl._create_shadow_window() 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/gl/__init__.py", line 205, in _create_shadow_window 
    _shadow_window = Window(width=1, height=1, visible=False) 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 163, in __init__ 
    super(XlibWindow, self).__init__(*args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/__init__.py", line 559, in __init__ 
    self._create() 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 353, in _create 
    self.set_caption(self._caption) 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 511, in set_caption 
    self._set_text_property('WM_NAME', caption, allow_utf8=False) 
    File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 785, in _set_text_property 
    buf = create_string_buffer(value.encode('ascii', 'ignore')) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 19: ordinal not in range(128) 
+1

Я не знаете, почему вы считаете, что у вас есть какой-либо контроль над тем, как произвольные модули Python обрабатывают данные, отличные от ASCII ... –

+0

@ IgnacioVazquez-Abrams, строковая переменная 'value', на которой происходит сбой кода, содержит путь, отличный от unicode, к' my_script.py' , Если в параметре '-m' был атрибут, я бы передал его для переноса пути' my_script.py' в юникоде - если бы это был способ добавить символ 'u''' до значения пути ... – dizcza

ответ

1

Это, кажется, ошибка в pyglet. Он использует sys.argv[0] в качестве заголовка окна по умолчанию, но он ожидает, что строка заголовка будет экземпляром unicode, который позже может быть отправлен encode в ASCII (игнорируя не представимые значения unicode). Тем не менее, в Python 2 sys.argv[0] будет байтовым (пример str) в некотором кодировании (я не уверен, что кодировка указана в любом месте или может отличаться от файловой системы к файловой системе). Когда вы пытаетесь выполнить encode уже закодированную байтовую ошибку, Python 2 сначала пытается декодировать строку до объекта unicode с использованием кодека ascii перед кодированием в соответствии с запросом.

Вы видите, что эта ошибка укусила вас только тогда, когда вы используете флаг -m, потому что только в этой ситуации (из протестированных вами способов) есть не-ASCII часть пути, включенная в sys.argv[0]. Когда вы звоните, python my_script.py, sys.argv[0] - "my_script.py". Когда вы используете -m, sys.argv[0] будет абсолютным путем к файлу скрипта (включая папку, отличную от ASCII).

Я не уверен, что такое правильное исправление, поскольку, как я уже упоминал выше, я не уверен, что кодировка, используемая sys.argv, хорошо указана в Python 2.Если вы хотите, чтобы исправить эту проблему как раз для вашей системы, вы, вероятно, может просто изменить эти строки в pyglet/window/__init__.py (они должны быть примерно 555-556 строк):

 if caption is None: 
      caption = sys.argv[0] 

To:

 if caption is None: 
      caption = sys.argv[0].decode("utf8") 
+0

Благодарим вас за подробный ответ. Я не буду изменять сценарии пакета, так как я хочу, чтобы мой проект мог работать со свежими установками pip. Как вы думаете, стоит ли создавать проблему в сообществе пиглетов? – dizcza

+0

У меня уже есть [здесь] (https://bitbucket.org/pyglet/pyglet/issues/74/pyglet-crashes-with-a-unicodeerror-on). Я хотел бы ссылаться на этот отчет здесь, но, похоже, я забыл, что не сделал этого. Пожалуйста, добавьте дополнительную информацию, если у вас есть какие-либо соображения! – Blckknght