Werkzeug: Windows console_scripts dipanggil dari reloader

Dibuat pada 13 Jun 2017  ·  14Komentar  ·  Sumber: pallets/werkzeug

Saya menjalankan apistar di python 3 dan menghadapi masalah yang membawa saya ke reloader 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

Menghapus use_reloader dari panggilan ke run_simple() berhasil. Setelah menggali beberapa komentar, saya menemukan bahwa https://github.com/pallets/werkzeug/blob/master/werkzeug/_reloader.py#L118 melakukan beberapa penyandian ke latin1 tetapi hanya ketika os adalah windows dan versi python adalah 2. Mungkinkah ini menyebabkan Kesalahan Sintaks Non-UTF-8 yang saya terima di python3?

Semua 14 komentar

Apakah ada contoh kecil yang dapat saya gunakan untuk mereproduksi ini? Saya tidak terbiasa menggunakan apistar dan tidak biasa menggunakan Windows.

Saya menggalinya sedikit lebih jauh. Masalahnya sebenarnya dengan _get_args_for_reloading() . Metode itu mengembalikan argumen yaitu ['python.exe', 'apistar.exe', 'run'] yang ketika diteruskan ke subprocess.call() menghasilkan kesalahan itu. Tidak ada bedanya dengan memanggil python.exe apistar.exe run dari baris perintah.

Jadi masalahnya bukan dengan pengkodean lingkungan seperti yang saya pikirkan semula. Mengingat bahwa itu akan menjadi kejadian yang sangat umum di kerangka kerja berbasis werkzueg lainnya, saya pikir perubahan pada metode ini untuk memperhitungkan fakta bahwa itu dapat dipanggil melalui console_script yang dihasilkan .exe akan menguntungkan semua pengguna windows.

Saya mengubah judul masalah untuk menjelaskan ini.

Jika metode ini membuang elemen sys.executable dari rv dalam pemeriksaan windows, maka reload berhasil:

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

Saya senang untuk meninjau PR jika Anda ingin mengirimkannya.

Saya pasti ingin, tetapi saya sedikit terjebak dalam menulis tes untuk ini. Saya hanya dapat melihat ini berfungsi dengan perpustakaan unittest.mock dan menambal sys.executable dan os.name, tetapi saya berasumsi bahwa ini tidak akan berfungsi untuk proyek Anda karena harus mendukung pengujian otomatis di 27 juga. Ada saran?

Juga apa strategi percabangan yang digunakan di sini? Apakah permintaan tarik untuk masalah bertentangan dengan cabang pemeliharaan saat ini?

Anda dapat bercabang dari pemeliharaan 0,12. Mari kita lihat dulu seperti apa patchnya, lalu cari tahu tesnya.

Saya memang mengajukan Permintaan Tarik. Tampaknya Travis CI gagal karena alasan yang tidak terkait dengan perubahan yang saya buat. Ini adalah Permintaan Tarik pertama saya jadi saya tidak tahu harus pergi ke mana dari sini.

Ini akan terjadi ketika Anda menginstal peluncur exe setuptools. Jika Anda menginstal melalui—up-to-date—pip, ia menginstal jenis baru peluncur exe (dari distlib ) yang menggabungkan skrip peluncur ke dalam exe di dalam zip yang dapat dieksekusi langsung oleh Python ( runpy docs ).

Ini tidak berarti ini tidak boleh diperbaiki, tetapi sangat membantu untuk mengetahui jika Anda tidak dapat mereproduksi ini. Itu masih akan terjadi jika Anda menginstal Flask dalam mode pengembangan ( pip install -e ) misalnya.

@androiddrew @davidism setiap update pada PR ini?

@segevfiner dapatkah Anda menambahkan sedikit lebih banyak detail ke komentar terbaru Anda? Apakah Anda menyarankan bahwa kami mungkin harus memperbaiki akar masalah di setuptools daripada di Flask?

@ewpete Akar penyebabnya adalah ketika menggunakan peluncur yang dihasilkan setuptools,
sys.argv[0] tidak dapat dieksekusi sebagai skrip Python karena ini adalah
peluncur exe. Script yang sebenarnya bernama seperti exe dengan - "-script"
ditambahkan dan exe memuat dan menjalankannya.

Perhatikan bahwa exe dapat dieksekusi secara langsung (Dan begitu juga skrip Python
dengan shebang yang saya yakini adalah apa yang dihasilkan oleh setuptools pada unices). Tetapi
melakukannya untuk skrip Python biasa di Windows tidak dapat diandalkan (Ketika
pylauncher tidak diinstal), karena akan diluncurkan dengan Python yang sewenang-wenang
yang terkait untuk file .py di registri, yang mungkin berbeda
daripada Python saat ini yang kami gunakan. Dan, tentu saja, hal yang sama berlaku untuk
skrip Python acak apa pun yang mungkin kita gunakan, yang bahkan mungkin tidak
dapat dieksekusi.

pip menginstal sebagai gantinya (melalui distlib) jenis peluncur exe baru yang memiliki
skrip peluncur yang dihasilkan ditambahkan di dalam zip di akhir
dapat dieksekusi. Ini akan dideteksi sebagai file zip dengan skrip __main__.py (A
zipapp) dan dapat diteruskan langsung ke Python untuk dieksekusi.

Untuk memperbaikinya di setuptools berarti menghasilkan kindbof yang serupa/sama
peluncur di setuptools. Dan dalam semangat http://xkcd.com/1172/ , ini
kemungkinan akan memecahkan kode yang mengharapkan peluncur dan percobaan setuptools
menggunakan file "*-script.py" untuk mengatasi masalah tersebut. Saya tidak memeriksa
apakah sudah ada masalah/pr tentang ini.

Mungkin tidak apa-apa untuk memiliki solusi kecil di sini sehingga Werkzeug
reloader bekerja bahkan di hadapan gaya setuptools saat ini
peluncur. Tapi itu benar-benar terserah pengelola proyek.

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

@androiddrew https://github.com/androiddrew @davidism
https://github.com/davidism ada pembaruan tentang PR ini?

@segevfiner https://github.com/segevfiner dapatkah Anda menambahkan sedikit lagi?
detail ke komentar terbaru Anda? Apakah Anda menyarankan bahwa kita harus
mungkin memperbaiki akar masalah di setuptools sebagai lawan di Flask?


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/pallets/werkzeug/issues/1136#issuecomment-347623921 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AXlg_8OSR3NdbPJzM87dyKPUA9NpXJ6ks5s7FT7gaJpZM4N5Fcb
.itu

@ewpete Ini adalah PR pertama saya. Saya melakukan yang terbaik untuk menulis tes, mengikuti panduan pengembang, dan menempatkan PR. Saya tidak memiliki banyak arahan tentang bagaimana melakukan ini, tetapi saya membuat perubahan yang disarankan dari komentar PR. Saya pikir itu selesai tetapi tidak pernah mendengar kabar apakah itu memenuhi harapan tim proyek. Belum melihatnya sejak itu, dan saya tidak tahu apa yang orang ingin lakukan dengannya.

Saya memiliki waktu yang sangat terbatas di beberapa proyek. Jangan khawatir, jangan lupakan ini.

@davidism Terima kasih, tidak hanya untuk menanggapi tetapi untuk melakukan pekerjaan yang baik menjaga proyek-proyek ini tetap hidup!

Meskipun ini masih belum digabungkan, satu kemungkinan perbaikan sementara adalah dengan melakukan monkeypatch fungsi _get_args_for_reloading() suatu tempat sebelum digunakan. Dalam hal skrip Flask, menambahkan ini di suatu tempat di awal file manage.py membantu:

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
Apakah halaman ini membantu?
0 / 5 - 0 peringkat