Untuk konversi kode Python2 ke Python3, versi Python & Django manakah yang paling cocok?


11

Saat ini saya sedang bekerja di perusahaan besar di mana kita perlu mengkonversi proyek Django besar python2 tua ke versi python3 jadi saya telah melakukan banyak penelitian terkait tetapi masih belum dapat menemukan jawaban yang sempurna terkait dengan versi Python dan Django yang paling cocok untuk konversi.

Saat ini saya menggunakan Python: 2.7.16 & Django: 1.9.13 dalam versi lama saya.

Siapa pun dapat menyarankan saya versi Python & Django yang paling cocok untuk versi lama di atas untuk konversi python2 ke python3.


Versi python3 saat ini adalah Python 3.8, dan versi terbaru Django adalah Django 3.0. Situs web Django merekomendasikan versi terbaru dari python 3 , yaitu 3.8. Apakah ada alasan khusus mengapa Anda tidak ingin mempercepat python dan django ke versi terbaru mereka?
Green Cloak Guy

2
Secara anekdot, saya baru menyadari beberapa hari yang lalu bahwa situs web berbasis Django yang telah saya pertahankan selama beberapa tahun sekarang benar-benar berjalan di server yang dihosting menggunakan python2.7, sedangkan saya telah menjalankannya secara lokal menggunakan python3. 7. Satu-satunya perbedaan yang saya temukan adalah ketika saya mencoba menggunakan f-string di suatu tempat untuk pertama kalinya dan versi server web macet; kalau tidak, ini sudah berjalan persis seperti yang diharapkan (persis sama) secara lokal dan jarak jauh, untuk keperluan pengujian dan penambahan fitur. Kesimpulan saya sepenuhnya anekdotal adalah bahwa Django umumnya kompatibel dengan sebagian besar hal.
Green Cloak Guy

1
untuk versi terbaru, saya telah menemukan bahwa beberapa orang tidak merekomendasikan karena dalam versi terbaru jika ada masalah terkait pembaruan baru maka kadang-kadang akan sulit untuk menemukan solusi sehingga dalam proyek saat ini saya tidak ingin membuat risiko semacam itu & juga untuk menguji tujuan, saya sudah mulai mengkonversi proyek saya ke versi terbaru python 3.7.3 dengan Django terbaru dan sudah menemukan 30 jenis masalah.
Bulan

Harus dicatat - pertanyaan ini muncul dalam audit peninjauan untuk saya. "Apakah ada dokumen atau referensi" sangat jelas di luar topik (meminta sumber daya di luar situs). Namun, saya yakin pertanyaan itu dapat diedit sedemikian rupa sehingga dapat mengarah ke jawaban yang diterima di bawah ini.
theMayer

Jawaban:


3

Saya pikir saya akan menambahkan sedikit pada strategi yang dianjurkan oleh jawaban Wim - dapatkan versi Django yang tepat bekerja pada 2.7 dan 3.x pertama - dan uraikan beberapa taktik yang bekerja untuk saya.

Python 2.7 adalah pod pelarian Anda, hingga Anda menarik pelatuk pada 3.x

  • tes Anda harus dijalankan pada keduanya
  • jangan gunakan fitur spesifik 3.x, seperti f-string
  • pertama Python 3.x, baru kemudian Django 2.x yang tidak berjalan pada 2.7
  • mulai lebih awal, jangan terlalu banyak menganalisis, tetapi hindari pendekatan big bang
    • file demi file pada awalnya.
    • mulai dengan kode level terendah, seperti pustaka utilitas, yang Anda miliki untuk test suites.
    • jika memungkinkan, cobalah untuk secara bertahap menggabungkan perubahan Anda ke 2,7 cabang produksi dan tetap memperbarui kode port 3.x Anda dengan perubahan prod.

Django versi minor mana yang memulai?

Kriteria saya di sini adalah bahwa migrasi Django dapat dilibatkan secara adil (dan sebenarnya membutuhkan lebih banyak pemikiran daripada 2 => 3 pekerjaan). Jadi saya akan pindah ke 1,11 terbaru dan terhebat dengan cara itu Anda sudah memberikan nilai kepada pengguna 2,7 Anda. Mungkin ada sejumlah shims kompatibilitas pra-2.x yang baik pada 1.11 dan Anda akan mendapatkan peringatan penghentian 2.x.

Versi minor apa dari Python 3.x untuk memulai?

Yang terbaik untuk mempertimbangkan semua sudut, seperti ketersediaan lib pihak ke-3 Anda, dukungan dari suite CI / devops Anda dan ketersediaan pada gambar OS server yang Anda pilih. Anda selalu dapat menginstal 3.8 dan mencoba menginstal pip dari requirement.txt Anda sendiri, misalnya.

Leverage git (atau apa pun SCM yang Anda gunakan) dan virtualenv .

  • pisahkan requirement.txtfile, tetapi ...
  • jika Anda memiliki git repo berbasis file, Anda dapat mengarahkan setiap venv pada codeline yang sama dengan a pip install -e <your directory>. itu berarti bahwa, di 2 terminal yang berbeda Anda dapat menjalankan 2.7 dan 3.x terhadap unittest yang sama.
  • Anda bahkan dapat menjalankan server Django 2.7 dan 3.x secara berdampingan pada port yang berbeda dan arahkan Firefox dan Chrome pada mereka.
  • sering melakukan (setidaknya pada cabang porting) dan belajar tentang git bisect .

memanfaatkan 2to3

Ya, itu akan merusak 2,7 kode dan Django jika Anda membiarkannya. Begitu...

  • jalankan dalam mode pratinjau atau terhadap satu file. melihat apa yang rusak tetapi juga melihat apa yang dilakukannya dengan benar.

  • throttle ke hanya konversi tertentu yang tidak melanggar 2.7 atau Django. print x=> print (x)dan except(Exception) as e2 tidak punya otak.

Ini adalah apa yang tampak seperti perintah tercekik saya:

2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
  • jalankan file-per-file sampai Anda benar-benar percaya diri.

gunakan sed atau awk daripada editor Anda untuk konversi massal.

Keuntungannya adalah, ketika Anda menjadi lebih sadar akan masalah spesifik aplikasi Anda, Anda dapat membuat serangkaian perubahan yang dapat dijalankan pada 1 file atau banyak file dan melakukan sebagian besar pekerjaan tanpa melanggar 2,7 atau Django. Terapkan ini setelah pas 2to3 Anda yang dipercantik . Itu membuat Anda dengan pembersihan sisa di editor Anda dan mendapatkan tes Anda untuk lulus.

(opsional) mulai hitam pada kode 2.7.

hitam yang merupakan pemformat kode, menggunakan Python 3 AST untuk menjalankan analisisnya. Itu tidak mencoba menjalankan kode, tetapi itu akan menandai kesalahan sintaksis yang mencegahnya mencapai tahap AST. Anda harus bekerja beberapa pip menginstal sihir global untuk sampai ke sana dan Anda harus membeli kegunaan hitam.

Orang lain telah melakukannya - belajarlah dari mereka.

Mendengarkan # 155 Langkah-langkah praktis untuk pindah ke Python 3 harus memberi Anda beberapa ide pekerjaan. Lihatlah tautan pertunjukan untuk itu. Mereka suka membicarakan langkah Instagram (?) Yang melibatkan penyesuaian bertahap menjalankan 2,7 kode ke sintaks 3.x pada basis kode umum, dan pada cabang git yang sama, sampai hari penarik-pemicu.

Lihat juga Panduan Porting Conservative Python 3

dan Instagram Melakukan Gerakan Lancar ke Python 3 - Stack Baru

Kesimpulan

Waktu Anda untuk Django 1.11 EOL (April 2020) agak singkat, jadi jika Anda memiliki 2+ sumber daya dev untuk dilemparkan padanya, saya akan mempertimbangkan melakukan hal berikut secara paralel:

  • DEV # 1: mulai dengan Django 1.11 bump (teorinya adalah bahwa Django 1.11 mungkin paling baik diposisikan sebagai titik tolak ke Django 2.x), menggunakan 2.7.

  • DEV # 2: memulai Python 3.6 / 3.7 dari kode utilitas non-Django Anda. Karena kode 2.7 kompatibel pada titik ini, gabungkan menjadi # 1 saat Anda menggunakannya.

Lihat bagaimana kedua tugas berjalan, menilai apa risiko proyek terkait Django dan seperti apa rasa sakit Python 3. Anda sudah kehilangan Python 2.7 EOL, tetapi kerangka kerja web yang usang mungkin lebih berbahaya daripada warisan Python 2.7, setidaknya selama beberapa bulan. Jadi saya tidak akan menunggu terlalu lama untuk mulai bermigrasi dari Django 1.9 dan pekerjaan Anda melakukannya tidak akan sia-sia. Ketika Anda melihat kemajuannya, Anda akan mulai melihat risiko proyek dengan lebih baik.

Kemajuan 2to3 awal Anda akan lambat, tetapi alat dan bimbingannya cukup bagus sehingga Anda akan dengan cepat menambah kecepatan jadi jangan terlalu memikirkannya sebelum mulai mengumpulkan pengalaman. Sisi Django tergantung pada paparan Anda untuk memecahkan perubahan dalam kerangka kerja itu sebabnya saya pikir yang terbaik untuk memulai lebih awal.

PS (pendapat kontroversial / pribadi) Saya tidak menggunakan enam atau banyak perpustakaan jembatan 2-ke-3 kaleng lainnya.

Itu bukan karena saya tidak percaya - itu brilian untuk lib pihak ke-3 - tetapi saya tidak ingin menambahkan ketergantungan permanen yang kompleks (dan saya terlalu malas untuk membaca dokumennya). Saya telah menulis kode 2,7 dalam sintaks yang kompatibel dengan 3.x untuk waktu yang lama jadi saya tidak benar-benar merasa perlu untuk menggunakannya. Jarak tempuh Anda mungkin bervariasi dan tidak memulai jalur ini jika sepertinya banyak pekerjaan .

Sebagai gantinya, saya membuat py223.py (57 LOC termasuk komentar) dengan jenis konten ini, yang sebagian besar berkaitan dengan solusi untuk penghentian dan perubahan nama di perpustakaan standar.

try:
    basestring_ = basestring
except (NameError,) as e:
    basestring_ = str

try:
    cmp_ = cmp
except (NameError,) as e:
    # from http://portingguide.readthedocs.io/en/latest/comparisons.html
    def cmp_(x, y):
        """
        Replacement for built-in function cmp that was removed in Python 3
        """
        return (x > y) - (x < y)

Kemudian impor dari py223 itu untuk mengatasi masalah khusus tersebut. Kemudian saya hanya akan parit impor dan memindahkan aneh isinstance(x, basestr_)untuk isinstance(x, str)tapi saya tahu sebelumnya ada sedikit untuk khawatir tentang.


Saran yang bagus. Hanya satu catatan, Django sendiri sudah digunakan sixuntuk lapisan kompatibilitas, jadi jika Anda ingin menggunakannya dalam proyek Django selama transisi, maka ini bukan "menambahkan ketergantungan permanen yang kompleks".
wim

@wim. Saya setuju dengan Anda kembali. enam, tetapi itu tergantung pada sudut pandang. Saya sudah mencatat bahwa ia datang dengan lib pihak ke-3, jadi itu tidak "biaya" dalam hal persyaratan dan dependensi keseluruhan. Namun saya - mungkin salah - menganggapnya kotak hitam besar / kutil di tengah kode saya . jika semua yang Anda lakukan adalah hal-hal seperti menguji string contoh / unicode / basestring dan jika Anda tahu bagaimana melakukannya sendiri, maka Anda tahu persis bagaimana cara membuat shims Anda keluar ketika mereka tidak diperlukan lagi. Saya akan memindahkannya sampai akhir.
JL Peyret

Itu pip install -e ...(dengan huruf kecil -e), kan?
thebjorn

mungkin itu. akan memperbaiki
JL Peyret

3

Saran saya adalah upgrade dulu ke Django==1.11.26 , yang merupakan versi terbaru dari Django yang mendukung Python 2 dan Python 3. Tetap di versi Python 2.7 Anda saat ini untuk saat ini.

Baca dengan cermat catatan rilis untuk 1.10.x dan 1.11.x, memeriksa penghentian dan memperbaiki apa pun yang berhenti berfungsi dari kode 1.9.x Anda. Hal-hal AKAN hancur. Django bergerak cepat. Untuk proyek Django besar, mungkin ada banyak perubahan kode yang diperlukan, dan jika Anda menggunakan banyak plugin atau pustaka pihak ketiga, Anda mungkin harus menyulap versinya. Beberapa dependensi pihak ketiga Anda mungkin telah ditinggalkan seluruhnya, jadi Anda harus mencari penggantian atau menghapus fitur-fiturnya.

Untuk menemukan catatan rilis untuk setiap peningkatan versi, cukup google "Apa yang baru di Django". Hit akan dengan cermat mendokumentasikan semua penghinaan dan perubahan:

Setelah webapp tampaknya berfungsi dengan baik pada Django 1.11, dengan semua tes berlalu (Anda lakukan memiliki suite tes, kan?) Maka Anda dapat melakukan Python 3 konversi, sementara menjaga versi Django yang sama. Django 1.11 mendukung hingga Python 3.7, sehingga itu akan menjadi versi yang bagus untuk ditargetkan. Harapkan unicode di semua tempat, karena konversi implisit antara byte dan teks telah hilang sekarang dan banyak webapp Python 2 mengandalkan itu.

Setelah proyek tampaknya berfungsi dengan baik pada Django 1.11 dan Python 3.7, maka Anda dapat berpikir untuk memutakhirkan ke Django 3.0, mengikuti proses yang sama seperti sebelumnya - membaca catatan rilis, membuat perubahan yang diperlukan, menjalankan test suite, dan memeriksa webapp di server dev secara manual.


1
Pasti cara untuk pergi. Dapatkan kode uji Anda untuk berjalan di 2.7 dan 3.x. Anda dapat memiliki 2 virtualenv berbeda yang menunjuk pada git repo yang sama dengannya pip install -E. Setelah unit test berjalan, mulailah uji coba penggunaan Django-on-3x dan teruskan kode berfungsi dalam 2 dan 3. Dengan beberapa pengkodean yang cermat dan berhati-hati untuk tidak membakar 2,7 jembatan Anda - misalnya tanpa string misalnya - peralihan akan menjadi sangat antiklimaks. Setelah 3.x sepenuhnya stabil, mulailah menggunakan kode 3.x saja. Keuntungannya adalah bahwa produksi 2.7 selalu dalam langkah sampai beralih.
JL Peyret

2

Saya akan memutakhirkan ke py3 pertama. Anda harus melihatnya di setup.pyrepo Django di cabang stable / 1.9.x ( https://github.com/django/django/blob/stable/1.9.x/setup.py ) untuk mengetahui bahwa py3 versi yang didukung adalah 3.4 (mati) dan 3.5.

Setelah Anda menggunakan py3.5 dan Django 1.9, Anda dapat memutakhirkan satu per satu hingga Anda mendapatkan versi yang ingin Anda akhiri. Misalnya Django 1.11 mendukung py3.5 dan py3.7, jadi

py27/dj19 -> py35/dj19 -> py35/dj1.11 -> py37/dj1.11 ... -> py37/dj2.2

dj2.2 adalah versi pertama yang mendukung py3.8, tapi saya mungkin akan berhenti di py37 / dj2.2 jika Anda bekerja di lingkungan yang biasanya konservatif.

Jika Anda memiliki paket lain, Anda harus menemukan kombinasi versi yang akan bekerja bersama pada setiap langkah. Memiliki rencana adalah kuncinya, dan memutakhirkan hanya satu komponen pada satu waktu biasanya akan menghemat waktu Anda.

Pustaka yang akan datang ( https://python-future.org/ ) akan membantu Anda dengan banyak situasi menjengkelkan saat Anda membutuhkan kode untuk dijalankan di py27 dan 3.x. Enam juga bagus. Saya akan menghindari menggulung lapisan kompatibilitas Anda sendiri (mengapa menciptakan kembali kemudi?)

Jika memungkinkan, cobalah untuk mendapatkan cakupan pengujian unit Anda hingga 75-85% sebelum memulai, dan tentukan mengatur pengujian otomatis pada versi "dari" dan "ke" untuk setiap langkah peningkatan. Pastikan Anda membaca dan memperbaiki semua peringatan dari Django sebelum memutakhirkan ke versi berikutnya - Django sangat peduli tentang kompatibilitas ke belakang, jadi saya biasanya menyarankan untuk memukul setiap versi minor di jalur peningkatan (atau setidaknya pastikan Anda membaca "mundur" ketidakcocokan "dan daftar penghentian untuk setiap versi minor).

Selamat mencoba (kami meningkatkan 300 + basis kode Kloc dari py27 / dj1.7 sekarang, jadi saya merasakan sakit Anda ;-)


1
+1 pada cakupan tes. Itu metrik kunci di sini, pendekatan apa pun yang akhirnya diambil. Ini benar-benar membantu ketika bereksperimen dengan perubahan kode meresap dan saya mengatakan ini sebagai seseorang yang sama sekali tidak aficionado tes TDD Merah / Hijau. Mencari cara untuk membuat baseline 2,7 hasil Anda dan peningkatan menjadi jauh lebih mudah.
JL Peyret

2

Saya memiliki masalah yang sama dengan proyek saya dan saya telah mencoba python 3.7.5 dengan Django versi 2.2.7.

Anda seharusnya tidak menggunakan python versi terbaru 3.8 atau Django latest versi 3.0 karena Anda mungkin ada kemungkinan bahwa untuk semua jenis bug Anda mungkin tidak bisa mendapatkan solusi yang tepat untuk versi terbaru.


Ini harus menjadi komentar
Bruno

-2

Anda harus mencoba memotret untuk versi saat ini. Python 3.8 dan Django 3.0. Enam perpustakaan akan membantu dengan beberapa perubahan konvensi. Apa pun cara Anda harus melakukan beberapa refactoring sehingga Anda mungkin membuatnya saat ini.


3
Apakah Anda pernah melakukan peningkatan Django? Ini hanya angan-angan. Langsung ke Python 3.8 dan Django 3.0 dari 2.7 / 1.9 akan hampir mustahil. Bahkan meningkatkan versi minor seperti Django 1.9 ke 1.10 bisa menjadi proses yang sulit, dengan banyak perubahan kode yang diperlukan.
wim

Ya saya sudah, tentu saja saya punya persetujuan kemewahan dan waktu untuk melakukan refactor lengkap dan membawa aplikasi saat ini. Sekali lagi ukuran aplikasi, logika, dan batasan waktu adalah masalah besar bagi kebanyakan orang, tetapi mereka tidak pernah menyebutkan ukuran aplikasi atau batasan waktu, jadi saya merekomendasikan pendapat saya tentang "solusi terbaik" atau "angan-angan";)
Dave

selain itu jika Anda harus khawatir tentang hal-hal yang mungkin dan berjalan pada Ubuntu LTS juga, Anda akan menemukan bahkan 3,7 dukungan kurang di Ubuntu 18,04. Podcast keamanan Saya mendengarkan saran membiarkan 3,8 menyelesaikan sedikit sampai rilis poin atau 2. -1 untuk risiko yang tidak perlu.
JL Peyret

Adakah rekomendasi podcast keamanan yang bagus?
Dave

Untuk Python dtk, listennotes.com/podcasts/talk-python-to-me/... Tapi saya pikir waspadalah terhadap 3.8 untuk sementara waktu yang lebih baru. Risky Business adalah podcast keamanan yang baik dan menghibur, terutama jika Anda mengikuti hubungan internasional. Permintaan maaf untuk downvote, tapi ya, apa yang berhasil dalam kasus Anda mungkin menjebak orang lain dalam konteks yang berbeda. Untuk konversi 2 hingga 3, lihat listennotes.com/podcasts/talk-python-to-me/…
JL Peyret
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.