Werkzeug: Reloader, python -m, dan sys.path

Dibuat pada 11 Nov 2013  ·  12Komentar  ·  Sumber: pallets/werkzeug

Lihat https://github.com/Kozea/WeasyPrint/issues/133

Apa yang terjadi adalah:

  • python -m weasyprint.navigator dijalankan
  • [sys.executable] + sys.argv adalah ['…/python', '…/weasyprint/navigator.py']
  • Reloader memunculkan subproses dengan cara itu
  • Proses anak tidak memiliki -m , jadi Python menambahkan direktori induk file .py ke sys.path
  • Werkzeug mencoba mengimpor html.entities stdlib
  • Ini salah mengimpor weasyprint/html.py
  • Barang rusak

Tidak ada orang di sini yang jelas-jelas melakukan kesalahan. Bagaimana saran Anda untuk menghadapi situasi ini? Apa pendapat Anda tentang memiliki …/weasyprint/navigator.py (yang diharapkan sebagian besar digunakan dengan python -m ) menghapus direktori induknya dari sys.path jika ada?

bug reloader

Komentar yang paling membantu

Saya memiliki masalah serupa, di mana impor relatif gagal karena reloader mengeksekusi modul sebagai non-paket:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Menggunakan komentar dari @untitaker , dengan Python <3.3 kita dapat mendeteksi jika python -m digunakan (hanya __loader__ ditentukan) dan memaksa reloader untuk juga menggunakannya dengan mengatur ulang sys.argv :

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Tapi ini solusi yang cukup hacky (dan hanya untuk Python <3.3).

Implementasi saat ini di # 531 tidak memperbaiki masalah khusus ini dan sayangnya saya tidak melihat bagaimana bisa.

Semua 12 komentar

Saya tidak berpikir itu tidak akan merugikan jika Werkzeug menelurkan subproses dengan argumen yang sebenarnya sama, menggunakan __loader__.fullname dengan Python 2 dan __loader__.name dengan Python 3 jika ada.

@untitaker , saya tidak mengerti apa yang Anda maksud. Apa __loader__ ?

Bisakah kita mendeteksi dengan Python jika python -m somemodule digunakan atau tidak?

Saya menemukan jawaban StackOverflow yang menjelaskan cara mendapatkan nama modul saat ini. Tes sederhana menunjukkan bahwa di Python 2, __loader__.fullname tersedia:

print(__loader__.fullname)

__loader__ global tidak ada jika file Python dijalankan tanpa -m , dan itu juga tidak ada di modul yang diimpor.

Dalam Python 3, baik modul dieksekusi dengan -m dan modul impor lainnya tampaknya memiliki __loader__ global, atribut fullname sekarang menjadi name . Tetapi di dalam setiap modul, atribut name memiliki nilai modul _current_.

Jadi, di Python 2 kami _can_ mendeteksi apakah kami menjalankan dengan -m , tetapi tidak di 3.

Deteksi juga sangat terbatas, jadi Anda hanya dapat mendeteksi di dalam modul yang dieksekusi secara langsung jika python -m digunakan dengan memeriksa variabel __loader__ . Juga, perilaku ini tampaknya jarang didokumentasikan, jadi saya tidak yakin apakah itu yang kami inginkan di Werkzeug.

Saya baru saja menemukan bug ini sendiri. Saya berharap bendera -m ada di sys.argv , tetapi yang pasti tidak.

Apakah ada solusi untuk ini?

Ya, salah satunya disajikan di https://github.com/mitsuhiko/flask/issues/1246

Pada 9 Juli 2015 15:08:30 CEST, Wayne Werner [email protected] menulis:

Saya baru saja menemukan bug ini sendiri. Saya mengharapkan bendera -m
hadir dalam sys.argv , tetapi yang pasti tidak.

Apakah ada solusi untuk ini?


Balas email ini secara langsung atau lihat di GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -119955695

Dikirim dari perangkat Android saya dengan K-9 Mail. Mohon maafkan singkatnya saya.

Saya memiliki masalah serupa, di mana impor relatif gagal karena reloader mengeksekusi modul sebagai non-paket:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Menggunakan komentar dari @untitaker , dengan Python <3.3 kita dapat mendeteksi jika python -m digunakan (hanya __loader__ ditentukan) dan memaksa reloader untuk juga menggunakannya dengan mengatur ulang sys.argv :

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Tapi ini solusi yang cukup hacky (dan hanya untuk Python <3.3).

Implementasi saat ini di # 531 tidak memperbaiki masalah khusus ini dan sayangnya saya tidak melihat bagaimana bisa.

Saya rasa saya mencoba untuk memperbaiki ini dengan loader sekali, tetapi hasilnya sangat luar biasa
perilaku yang berbeda dari 2 ke 3.

Pada Kamis, 10 Sep 2015 pukul 13.26.56 -0700, Martijn Vermaat menulis:

Saya memiliki masalah serupa, di mana impor relatif gagal karena reloader mengeksekusi modul sebagai non-paket:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Menggunakan komentar dari @untitaker , dengan Python <3.3 kita dapat mendeteksi jika python -m digunakan (hanya __loader__ ditentukan) dan memaksa reloader untuk juga menggunakannya dengan mengatur ulang sys.argv :

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Tapi ini solusi yang cukup hacky (dan hanya untuk Python <3.3).


Balas email ini secara langsung atau lihat di GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -139369694

Dengan sedih,

$ python -m werkzeug.serving weasyprint. navigator: app --reload --debug

  • Berjalan di http://127.0.0.1 : 5000 / (Tekan CTRL + C untuk keluar)
  • Memulai kembali dengan stat
    Traceback (panggilan terakhir terakhir):
    File "/usr/lib/python2.7/site-packages/werkzeug/serving.py", baris 45, di
    dari ._compat import PY2
    ValueError: Upaya impor relatif dalam non-paket

Bug python ini tidak dapat diperbaiki dengan benar dengan python, jadi saya sarankan untuk menyediakan skrip konsol

Ada perubahan dalam hal ini? Baru saja mengalami masalah ini ... (Python 3.6, tidak ada weasyprint, hanya python -m werkzeug.serving app:application )

Saya berhasil mengatasi masalah ini dengan melakukan sesuatu seperti:

PYTHONPATH=$PWD:$PYTHONPATH python -m myapp.entrypoints.website

_Edit: menyadari solusinya tepat di atas : arrow_up: _

Apakah halaman ini membantu?
0 / 5 - 0 peringkat