Werkzeug: Windows console_scripts, вызываемые из перезагрузчика

Созданный на 13 июн. 2017  ·  14Комментарии  ·  Источник: pallets/werkzeug

Я запускаю apistar на python 3 и сталкиваюсь с проблемой, которая привела меня к перезагрузчику werkzeug.

(fresh) C:\Users\uskaxb07\PycharmProjects\testapi>apistar run
Starting up...
 * Restarting with stat
  File "C:\Users\uskaxb07\env\fresh\Scripts\apistar.exe", line 1
SyntaxError: Non-UTF-8 code starting with '\x90' in file C:\Users\uskaxb07\env\fresh\Scripts\apistar.exe on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Удаление use_reloader из вызова run_simple() работает. Покопавшись в нескольких комментариях, я обнаружил, что https://github.com/pallets/werkzeug/blob/master/werkzeug/_reloader.py#L118 выполняет некоторую кодировку для latin1, но только тогда, когда ОС - это окна и версия Python равно 2. Может ли это быть причиной синтаксической ошибки, отличной от UTF-8, которую я получаю в python3?

Все 14 Комментарий

Есть небольшой пример, который я могу использовать, чтобы воспроизвести это? Я не знаком с использованием apistar и не пользуюсь Windows регулярно.

Я углубился в это немного дальше. Проблема на самом деле связана с ['python.exe', 'apistar.exe', 'run'] которые при передаче в subprocess.call() генерируют эту ошибку. Это ничем не отличается от вызова python.exe apistar.exe run из командной строки.

Так что проблема не в кодировке окружения, как я думал изначально. Учитывая, что это было бы очень распространенным явлением в других фреймворках, основанных на werkzueg, я думаю, что изменение этого метода, чтобы учесть тот факт, что он может быть вызван через сгенерированный console_script .exe, принесет пользу всем пользователям Windows.

Я меняю название проблемы, чтобы учесть это.

Если этот метод удалил элемент sys.executable rv в рамках проверки Windows, то перезагрузка прошла успешно:

def _get_args_for_reloading():
    """Returns the executable. This contains a workaround for windows
    if the executable is incorrectly reported to not have the .exe
    extension which can cause bugs on reloading.
    """
    rv = [sys.executable]
    py_script = sys.argv[0]
    if os.name == 'nt' and not os.path.exists(py_script) and \
       os.path.exists(py_script + '.exe'):
        py_script += '.exe'
        rv.pop()
    rv.append(py_script)
    rv.extend(sys.argv[1:])
    return rv

Я буду рад просмотреть PR, если вы хотите его отправить.

Я определенно хотел бы, но я немного зациклился на написании теста для этого. Я вижу, как это работает только с библиотекой unittest.mock и исправляет sys.executable и os.name, но я предполагаю, что это не сработает для вашего проекта, поскольку он также должен поддерживать автоматическое тестирование в 27. Любой совет?

И какая стратегия ветвления здесь используется? Идут ли запросы на вытягивание для проблем с текущей веткой обслуживания?

Вы можете перейти от 0.12-обслуживание. Давайте сначала посмотрим, как выглядит патч, а затем разберемся с тестом.

Я отправил запрос на слияние. Похоже, что Travis CI дает сбой по причинам, не связанным с внесенными мной изменениями. Это мой первый запрос на слияние, поэтому я не знаю, куда идти.

Это произойдет, если у вас установлены средства запуска для запуска программы setuptools. Если вы устанавливаете через - последнюю версию - pip, он устанавливает новый вид исполняемых программ запуска (из объединяют сценарий запуска в exe внутри zip-архива, который Python может запускать напрямую ( runpy docs ).

Это не означает, что это не должно быть исправлено, но это полезно знать, если вы не можете воспроизвести это. Это все равно произойдет, если вы установите Flask в режиме разработки (например, pip install -e ).

@androiddrew @davidism есть ли обновления по этому

@segevfiner, не могли бы вы добавить немного подробностей к своему последнему комментарию? Вы предлагаете, чтобы мы, вероятно, должны исправить основную причину в setuptools, а не во Flask?

@ewpete Основная причина в том, что при использовании программ запуска, сгенерированных setuptools,
sys.argv [0] не исполняется как скрипт Python, так как это
пусковая установка exe. Фактический сценарий называется как exe с - "-script".
добавлен, и exe загружает и запускает его.

Обратите внимание, что exe может быть запущен напрямую (как и сценарий Python
с shebang, который, как я считаю, генерирует setuptools на unices). Но
делать это для простых скриптов Python в Windows ненадежно (когда
pylauncher не установлен), так как запускается с произвольным Python
который связан с файлами .py в реестре, которые могут отличаться
чем текущий Python, который мы используем. И, конечно же, то же самое относится и к
любой случайный скрипт Python, из которого мы могли бы быть вызваны, который может даже не быть
исполняемый файл.

pip вместо этого устанавливает (через distlib) новую программу запуска exe, которая имеет
сгенерированный скрипт запуска, добавленный в zip в конце
исполняемый файл. Он будет обнаружен как zip-файл со сценарием __main__.py (A
zipapp) и может быть передан непосредственно на выполнение в Python.

Чтобы исправить это в setuptools, нужно будет создать похожий / такой же вид
пусковые установки в setuptools. И в духе http://xkcd.com/1172/ этот
скорее всего, сломает код, который ожидает запусков setuptools и пытается
используя файлы «* -script.py», чтобы обойти проблему. Я не проверял
есть ли уже вопрос / PR по этому поводу.

Возможно, здесь есть небольшой обходной путь, чтобы Werkzeug
перезагрузчик работает даже при наличии текущего стиля в setuptools
пусковые установки. Но это действительно дело разработчиков проекта.

תאריך 28 וב '2017 20:46, "ewpete" [email protected] תב:

@androiddrew https://github.com/androiddrew @davidism
https://github.com/davidism есть ли обновления по этому PR?

@segevfiner https://github.com/segevfiner можешь добавить еще немного?
подробно к вашему последнему комментарию? Вы предлагаете, чтобы мы
возможно, исправить основную причину в setuptools, а не во Flask?

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/pallets/werkzeug/issues/1136#issuecomment-347623921 ,
или отключить поток
https://github.com/notifications/unsubscribe-auth/AXlg_8OSR3NdbPJzM87dyKPUAA9NpXJ6ks5s7FT7gaJpZM4N5Fcb
.The

@ewpete Это был мой первый пиар. Я приложил все усилия, чтобы написать тесты, следовать руководству разработчиков и разместить PR. У меня не было особых указаний, как это сделать, но я внес предложенные изменения из комментариев по связям с общественностью. Я думал, что он завершен, но никогда не слышал, отвечает ли он ожиданиям команды проекта. С тех пор не смотрел на это, и я не знаю, что люди хотят с этим делать.

У меня очень мало времени на несколько проектов. Не волнуйтесь, не забыли об этом.

@davidism Спасибо, не только за ответ, но и за хорошую работу по поддержанию жизни этих проектов!

Хотя это все еще не объединено, одно из возможных временных исправлений - это обезвредить функцию _get_args_for_reloading() где-нибудь до того, как она будет использована. В случае сценария Flask помогает добавить это где-нибудь в начале файла manage.py :

import werkzeug._reloader
import os, sys

def _get_args_for_reloading():
    rv = [sys.executable]
    py_script = sys.argv[0]
    if os.name == 'nt' and not os.path.exists(py_script) and \
       os.path.exists(py_script + '.exe'):
        py_script += '.exe'
    if os.path.splitext(rv[0])[1] == '.exe' and os.path.splitext(py_script)[1] == '.exe':
        rv.pop()
    rv.append(py_script)
    rv.extend(sys.argv[1:])
    return rv
werkzeug._reloader._get_args_for_reloading = _get_args_for_reloading
Была ли эта страница полезной?
0 / 5 - 0 рейтинги