Pipenv: Proposal: pola `pipenv` dan antipatterns untuk proyek perpustakaan python

Dibuat pada 5 Apr 2018  ·  74Komentar  ·  Sumber: pypa/pipenv

Meretas maya Saya belajar beberapa pelajaran yang menghasilkan proposal berikut tentang penggunaan pipenv direkomendasikan di perpustakaan python. Saya mengharapkan orang lain untuk meninjau proposal dan jika kita mencapai kesepakatan, teks (diperbarui) dapat berakhir di pipenv docs.

pipenv pola dan antipatterns untuk proyek perpustakaan python

EDIT
Berikut ini paling baik diterapkan untuk pustaka python umum (kebanyakan Open Source), yang seharusnya berjalan pada versi dan OS python yang berbeda. Perpustakaan yang dikembangkan di lingkungan Perusahaan yang ketat mungkin berbeda kasusnya (pastikan untuk meninjau semua bagian Masalah).

AKHIR EDIT

TL;DR : Menambahkan file pipenv ke dalam proyek perpustakaan python kemungkinan akan menimbulkan kerumitan ekstra dan dapat menyembunyikan beberapa kesalahan tanpa menambahkan apa pun ke keamanan perpustakaan. Untuk alasan ini, jauhkan Pipfile , Pipfile.lock dan .env dari kontrol sumber perpustakaan.

Anda akan dapat menggunakan kekuatan penuh pipenv terlepas dari file yang tinggal di .gitignore .

Pustaka Python versus aplikasi python

Dengan pustaka python yang saya maksud adalah sebuah proyek, biasanya memiliki setup.py , yang ditargetkan untuk distribusi dan penggunaan pada berbagai platform yang berbeda dalam versi python dan/atau OS.

Contohnya adalah maya , requests , flask dll.

Di sisi lain (bukan pustaka python) ada aplikasi yang ditargetkan untuk juru bahasa python tertentu, OS dan sering digunakan di lingkungan yang sangat konsisten.

pipfile menjelaskan perbedaan ini dengan sangat baik dalam Pipfile vs setup.py .

Apa itu pipenv (alat penerapan)

Saya sepenuhnya setuju dengan pernyataan tersebut, bahwa pipenv adalah alat penyebaran karena memungkinkan untuk:

  • tentukan persyaratan ketat ( Pipfile.lock ) untuk penerapan lingkungan virtual
  • terapkan persyaratan ketat tersebut dengan cara yang dapat direproduksi pada mesin yang berbeda

Ini membantu ketika seseorang harus menyebarkan aplikasi atau mengembangkan di lingkungan python yang sangat konsisten di beberapa pengembang.

Memanggil alat pengemasan pipenv menyesatkan jika seseorang mengharapkannya untuk membuat pustaka python atau terlibat secara mendalam dalam pembuatannya. Ya, pipenv dapat banyak membantu (dalam pengembangan perpustakaan lokal) tetapi mungkin dapat membahayakan (seringkali dalam pengujian CI ketika digunakan tanpa pemikiran yang lebih dalam).

Menerapkan "alasan keamanan" dalam konteks yang salah

TL;DR : pipenv menyediakan lingkungan yang aman melalui penerapan dependensi konkret yang disetujui yang dijelaskan dalam file Pipfile.lock dan pustaka python hanya diizinkan untuk mendefinisikan dependensi abstrak (sehingga tidak dapat memberikan Pipfile.lock ).

pipenv bersinar dalam skenario penerapan mengikuti langkah-langkah berikut:

  • tentukan dependensi abstrak (melalui Pipfile )
  • hasilkan darinya dependensi konkret yang menghasilkan Pipfile.lock
  • buat lingkungan python (virtual) yang mencerminkan dependensi konkret itu
  • jalankan tes untuk memastikan, lingkungan yang diberikan berfungsi seperti yang diharapkan dan aman
  • lepaskan "emas" yang diuji Pipfile.lock sebagai definisi lingkungan python yang disetujui
  • yang lain dapat menggunakan pipenv sync untuk menerapkan "the golden" Pipfile.lock tempat lain untuk mendapatkan lingkungan python yang identik.

Dengan pengembangan perpustakaan python, seseorang tidak dapat mencapai keamanan seperti itu, karena perpustakaan tidak boleh mendefinisikan dependensi konkret . Melanggar aturan ini (sehingga mencoba mendeklarasikan dependensi konkret oleh pustaka python) menghasilkan masalah seperti:

  • masalah untuk menemukan versi perpustakaan bersama yang memuaskan (setiap paket ketat mendefinisikan versi yang tepat dari perpustakaan bersama dan sangat mungkin versinya akan berbeda dan mencegah menemukan versi yang dapat diterima secara umum)
  • dependensi konkret mungkin bergantung pada versi python, OS atau penanda lingkungan lainnya dan mencoba menginstal paket dalam konteks yang berbeda dapat dengan mudah gagal memenuhi beberapa aturan yang ditentukan dalam dependensi abstrak asli.

Masalah: Menyembunyikan dependensi yang ditentukan setup.py rusak

setup.py akan mendefinisikan semua dependensi abstrak melalui install_requires .

Jika Pipfile mendefinisikan dependensi tersebut juga, ia dapat dengan mudah menyembunyikan masalah seperti:

  • ketergantungan yang hilang di install_requires
  • Pipfile mendefinisikan aturan khusus (rentang versi dll.) untuk ketergantungan dan install_requires tidak.

Untuk mencegahnya, ikuti aturan berikut:

  • dependensi yang ditentukan perpustakaan tidak boleh muncul di Pipfile
  • bagian [packages] di Pipfile harus kosong atau hanya mendefinisikan ketergantungan tunggal pada perpustakaan itu sendiri.

Masalah: Pipfile.lock dalam repositori

Menyimpan Pipfile.lock (biasanya untuk "alasan keamanan") di repositori perpustakaan salah, karena:

  • dependensi yang dijelaskan kemungkinan tidak valid untuk versi python yang berbeda atau di OS lain
  • pengembang dipaksa untuk memperbarui file tidak hanya ketika mereka menambah/menghapus beberapa ketergantungan, tetapi juga ketika perpustakaan lain diperbarui dan mungkin dapat digunakan di dalam perpustakaan.

Untuk mencegahnya, seseorang harus:

  • hapus Pipfile.lock dari repositori dan tambahkan ke .gitignore

Masalah: Bersaing dengan tox (menyembunyikan usedevelop )

Jika tox.ini berisi entri bagian commands seperti:

  • pipenv install
  • pipenv install --dev
  • pipenv lock

seringkali menjadi masalah, karena:

  • pipenv install hanya akan menginstal perpustakaan itu sendiri, dan tox (secara default) juga melakukannya. Selain duplicity, ia juga mencegah usedevelop=True dan usedevelop=False dalam tox.ini karena Pipenv dapat mengekspresikannya hanya dalam satu varian (dan tox.ini memungkinkan perbedaan di lingkungan yang berbeda).

Untuk mencegahnya, seseorang harus:

Masalah: Merusak build, jika pipenv gagal

pipenv sedang dalam pengembangan yang berat dan kadang-kadang bisa rusak. Jika masalah tersebut merusak build CI Anda, ada kegagalan yang dapat dicegah dengan tidak menggunakan pipenv dan menggunakan alat tradisional (yang sering kali lebih matang).

Untuk mencegahnya, seseorang harus:

  • pikirkan dua kali sebelum menambahkan pipenv ke dalam skrip pembuatan CI, tox.ini atau tempat serupa. Apakah Anda tahu nilai apa yang Anda dapatkan dari menambahkannya? Mungkinkah pekerjaan dilakukan dengan perkakas yang ada?
  • jangan menambahkannya "hanya untuk alasan keamanan" atau karena "semua orang melakukannya".

Ringkasan

Pertanyaan kunci tentang peran pipenv dalam pengembangan pustaka python adalah:

  • Nilai apa yang benar-benar dihasilkan oleh pipenv ? A: Alat manajemen virtualenv.
  • Apa kasus penggunaan yang relevan untuk pipenv ? A: Kelola virtualenv.
  • Haruskah itu muncul di repositori perpustakaan? J: TIDAK.

Beberapa detail dan trik lainnya menyusul.

pipenv tidak akan menambahkan keamanan apa pun ke paket Anda

Jangan memaksakannya ke dalam proyek hanya karena semua orang melakukannya atau karena Anda mengharapkan keamanan ekstra. Ini akan mengecewakan Anda.

Mengamankan dengan menggunakan dependensi konkret (dan disetujui) akan dilakukan di fase selanjutnya dalam aplikasi yang akan menggunakan perpustakaan Anda.

Jauhkan file Pipfile , Pipfile.lock dan .env dari repositori

Masukkan file ke .gitignore .

Pipfile mudah dibuat ulang seperti yang ditunjukkan di bawah ini karena sebagian besar atau semua persyaratan sudah ditentukan dalam setup.py . Dan file .env mungkin berisi informasi pribadi, yang tidak boleh dibagikan.

Menyimpan file-file ini dari repositori akan mencegah semua masalah, yang mungkin terjadi dengan CI build saat menggunakan pipenv dalam situasi yang tidak sesuai.

pipenv sebagai kotak peralatan pribadi pengembang

pipenv dapat menyederhanakan pekerjaan pengembang sebagai alat manajemen virtualenv.

Triknya adalah mempelajari, cara cepat membuat ulang file terkait pipenv (pribadi) Anda, misalnya:

$ cd <project_repository>
$ # your library will bring the dependencies (via install_requires in setup.py)
$ pipenv install -e .   
$ # add more dev tools you preffer 
$ pipenv install --dev ipython pdbpp
$ # start hacking
$ pipenv shell
...

Gunakan file .env jika Anda membutuhkan metode yang mudah untuk mengatur variabel lingkungan.

Ingat: Jauhkan penggunaan pipenv dari build CI Anda dan hidup Anda akan lebih sederhana.

Trik: Gunakan kemampuan setup.py untuk mendeklarasikan dependensi ekstra

Di setup.py gunakan bagian extras_requires :

from setuptools import setup

setup(
    name='mypackage',
    ....,
    install_requires=["jinja2", "simplejson"],
    extras_require={
        'tests': ['pytest', 'pyyaml'],
        'pg': ['psycopg2'],
    },
    ....
)

Untuk menginstal semua dependensi yang dideklarasikan untuk tests ekstra:

$ pipenv install -e .[tests]

Perhatikan, bahwa itu akan selalu menyertakan dependensi install_requires .

Metode ini tidak mengizinkan pemisahan dependensi menjadi bagian default dan dev, tetapi ini tidak akan menjadi masalah nyata dalam skenario yang diharapkan.

Discussion Type

Komentar yang paling membantu

@Moritz90 Beberapa milis Python akan menjadi tempat yang baik untuk mengadakan diskusi ini.

pypa-dev adalah yang paling pasti untuk diskusi yang berpusat pada kemasan Python, dan ekosistem di sekitarnya. Saya mungkin akan mulai di sini jika saya memposting diskusi serupa.

python-ideas adalah tempat untuk mendiskusikan ide, dan memiliki visibilitas yang cukup tinggi ke seluruh komunitas Python. Ini juga akan menjadi titik awal yang baik jika Anda ingin mendorong ini ke tingkat PEP (pada akhirnya Anda akan melakukannya, saya pikir).

Semua 74 komentar

Ini sangat mengesankan, terima kasih banyak untuk kompilasi. Pasti akan mengulas lebih detail sedikit

/cc @uranusjr @jtratner @ncoghlan

Beberapa referensi untuk masalah maya :

  • kennethreitz/maya#138 (HapusPipfile.lock dari repositori)
  • kennethreitz/maya#139 (Lewati run pipenv di tox.ini ...)
  • kennethreitz/maya#145 (perbaiki pendulum>=1.0 di setup.py: versi ada di Pipfile tetapi hilang di setup.py)
  • kennethreitz/maya#143 (PR menunjukkan bagaimana masalah pipenv merusak seluruh rangkaian Travis)
  • kennethreitz/maya#144 (Penggunaan pipenv Refactor PR menurut praktik terbaik semi-resmi)

Saya juga menyukai ini. Mungkin kita harus menambahkan ini ke dokumentasi Pipenv, atau bahkan Panduan Pengguna Python Packaging .

Akibat wajar dari saran di atas tampaknya adalah "meninggalkan build CI yang deterministik/dapat direproduksi", yang menurut saya sebagai anti-pola yang sangat besar.

Apa yang Anda usulkan sebagai alternatif yang masih memungkinkan determinisme?

@tsiq-oliverc Deterministic build memiliki tempatnya saat ini, sebuah aplikasi akan dibangun.

Bayangkan upaya berikut untuk melakukan build pustaka python yang benar-benar deterministik:

  • build harus didasarkan pada Pipfile.lock
  • setiap konteks eksekusi (kombinasi dari setiap varian python dan OS) mungkin memiliki Pipfile.lock dihasilkan dari dependensi abstrak perpustakaan yang ditentukan dalam Pipfile
  • Repositori harus menyediakan instance Pipfile.lock ditentukan dalam repositori. Perhatikan, bahwa membangun Pipfile.lock secara otomatis selama CI build tidak menambahkan determinisme apa pun

Ini banyak usaha ekstra. Dan apa yang Anda dapatkan adalah perpustakaan, yang akan diinstal dalam konteks yang berbeda (misalnya seminggu kemudian instalasi standar akan mengambil ketergantungan yang ditingkatkan atau dua) dan yang tidak akan mendapatkan apa pun dari fakta, Anda menggunakan Pipfile.lock , yang saat ini sudah usang.

Konfliknya adalah fakta bahwa perpustakaan tidak boleh mendefinisikan dependensi ketat di dalamnya.

Jika menurut Anda, ada alternatif lain untuk mendapatkan build deterministik untuk pustaka python - jelaskan.

@vlcinsky - Jika konsumen perpustakaan Anda menggunakan versi dependensi yang berbeda, dll. maka itu di luar kendali Anda. Jadi saya setuju tidak ada cara yang layak bagi pengelola perpustakaan untuk mengelolanya.

Tapi tujuannya di sini mungkin cakupannya jauh lebih kecil. Secara khusus, saya akan melihat tujuan untuk pengelola perpustakaan sebagai berikut (yang kira-kira setara):

  1. Jika Anda menjalankan CI Anda dua kali, Anda dijamin mendapatkan hasil yang sama (terlepas dari masalah jaringan!).
  2. Anda dapat membuat ulang (dan dengan demikian men-debug) perilaku yang Anda amati di CI secara lokal, bahkan jika itu berarti menjalankan Docker/etc. lokal.
  3. Anda dapat dengan yakin mengatakan "Perpustakaan saya berperilaku seperti yang diharapkan dengan versi ketergantungan X, Y, Z" kepada konsumen Anda.

Jika salah satu dari ketiga hal itu tidak berlaku, menurut saya itu bertentangan dengan kontrol kualitas.

Jadi ya, saya akan mengatakan bahwa jika Anda menjamin untuk mendukung varian Python A, B dan C untuk konsumen Anda, dan mereka berperilaku cukup berbeda sehingga satu lockfile (dll.) tidak memotongnya, maka Anda harus memiliki tiga lockfiles (atau apa pun).

Saya belum cukup menggunakan Pipenv untuk mengetahui betapa mudahnya hal itu dalam praktiknya.

Saat ini saya sedang mempertimbangkan untuk menambahkan Pipfile s ke beberapa proyek perpustakaan untuk sistem CI juga.

Saya benar-benar membutuhkan penguncian ketergantungan (+ hashing) untuk mematuhi pedoman keamanan di seluruh perusahaan dan saat ini saya tidak perlu menguji dengan versi Python yang berbeda, karena hanya ada satu yang didukung secara resmi. Dan fakta bahwa pipenv menyederhanakan pengaturan lingkungan pengembangan lokal, termasuk virtualenv, adalah efek samping yang bagus.

Dan apa yang Anda dapatkan adalah perpustakaan, yang akan diinstal dalam konteks yang berbeda (misalnya seminggu kemudian instalasi standar akan mengambil ketergantungan yang ditingkatkan atau dua) dan yang tidak akan mendapatkan apa pun dari fakta, Anda menggunakan Pipfile.lock , yang saat ini sudah usang.

Ini tidak benar secara universal. Di dunia perangkat lunak perusahaan, Anda masih memiliki lingkungan yang sangat spesifik yang didukung secara resmi dan masalah keamanan dalam ketergantungan mengakibatkan produk Anda diperbarui daripada pelanggan memperbarui ketergantungan itu sendiri.

(Ya, saya sedang berbicara tentang perpustakaan, bukan aplikasi di sini ...)

@Moritz90 skenario Anda adalah untuk pustaka python di lingkungan perusahaan dan di sana pipenv dapat membantu karena ini adalah lingkungan yang jauh lebih deterministik.

Deskripsi saya ditujukan pada pustaka python umum seperti flask , request , maya dll. di mana konteksnya jauh lebih bervariasi. Mencoba memperbaiki beberapa hal di maya Saya menjadi frustrasi saat belajar, bahwa dalam banyak kasus penggunaan pipenv menimbulkan masalah nyata (biasanya menyembunyikan masalah yang biasanya terdeteksi) sementara tidak memberikan banyak atau tambahan apa pun nilai.

Mendapatkan build deterministik adalah hal yang baik, tetapi memerlukan biaya. Dan jika dilakukan salah, Anda dapat membayar ekstra untuk hasil berkualitas lebih rendah - dan inilah yang ingin saya cegah.

Saya berpendapat ini adalah salah satu contoh kami tidak ingin build menjadi benar - == , Anda berkomitmen untuk mempertahankan dukungan ke beberapa versi secara default, dan harus mendesain pustaka seperti itu. Peningkatan dependensi yang merusak build di CI sebenarnya adalah hal yang baik karena mengekspos bug di perpustakaan. Ketergantungan yang sepenuhnya deterministik (seperti yang dikelola oleh Pipenv) akan menutupinya. Akan tetap bermanfaat untuk dapat menjadi determinitik ketika Anda menginginkannya, yang umumnya bukan yang terbaik.

@uranusjr - Tentu. Saya setuju bahwa jika keinginannya adalah "pembangunan non-deterministik", maka saran di atas mungkin masuk akal. Faktanya, ini hampir merupakan kesetaraan logis, dan dapat dinyatakan dengan lebih ringkas: "Jika Anda tidak ingin build deterministik, maka jangan gunakan alat ( pipenv ) yang tujuannya adalah untuk memastikan build deterministik" .

Tapi itu tentu bukan tujuan yang diinginkan secara umum.

@tsiq-oliverc definisi lingkup yang bagus - mendukung diskusi terfokus. Saya akan menambahkan satu persyaratan lagi: Determinisme CI tidak boleh menyembunyikan kemungkinan masalah dalam pustaka yang diuji.

Jika kita menggunakan Pipenv.lock , membuat virtualenv berdasarkan itu dan menjalankan tes CI dari perpustakaan, kita melakukan bagian dari fungsionalitas yang seharusnya dilakukan perpustakaan - menginstal dependensi yang tepat. Jika perpustakaan entah bagaimana rusak dalam hal ini - lingkungan yang sudah diinstal sebelumnya akan menyembunyikan masalah ini.

Bagi saya tampaknya lebih penting untuk mendeteksi masalah dalam perpustakaan daripada menjalankan CI dengan cara deterministik. Jika ada cara untuk melakukan keduanya (misalnya menjalankan tes di belakang indeks pypi pribadi, yang juga dapat mendukung determinisme) saya tidak punya masalah, tetapi jika ada konflik, saya punya prioritas.

Jangan salah paham: tidak ada keinginan untuk menjalankan build non-deterministik, keinginan saya adalah menjalankan CI build, yang akan mendeteksi sebanyak mungkin masalah.

@vlcinsky Tentu, saya hanya ingin membagikan pengalaman saya untuk memastikan bahwa dokumentasi yang diperbarui juga mencerminkannya. Dokumentasi saat ini melakukan pekerjaan yang baik dalam menjelaskan pengorbanan:

Untuk perpustakaan, tentukan dependensi abstrak melalui install_requires di setup.py. [...]
Untuk aplikasi, tentukan dependensi dan di mana mendapatkannya di Pipfile dan gunakan file ini untuk memperbarui kumpulan dependensi konkret di Pipfile.lock. [...]
Tentu saja, Pipfile dan pipenv masih berguna untuk pengembang perpustakaan, karena dapat digunakan untuk mendefinisikan lingkungan pengembangan atau pengujian.
Dan, tentu saja, ada proyek yang perbedaan antara perpustakaan dan aplikasi tidak begitu jelas.

(Menyoroti bagian yang berlaku dalam kasus saya.)

Saya hanya ingin memastikan itu tetap seperti itu. Saya pikir posting asli Anda mengandung terlalu banyak pernyataan menyeluruh tanpa penafian bahwa Anda sedang berbicara tentang proyek sumber terbuka yang akan diterbitkan di PyPI.

@Moritz90 Saya sepenuhnya setuju. Saya mencoba untuk menyorot fokus itu tetapi saya bisa membuatnya lebih terlihat.

@Moritz90 Saya menambahkan catatan pengantar yang mencerminkan komentar Anda.

@vlcinsky - Itu masuk akal. Saya memahami bahwa Anda tidak secara eksplisit ingin non-deterministik membangun, tapi saya pikir bahwa itu tak terhindarkan setara dengan apa yang Anda lakukan inginkan (yaitu masalah menangkap saat dependensi hulu Anda update).

Berpikir keras, apa cara terbaik untuk menyelesaikan dua tujuan yang saling bertentangan ini? Salah satu kemungkinannya adalah memiliki proses CI dua fase:

  1. Fase deterministik. Memanfaatkan Pipfile.lock dalam repo Anda, sehingga sepenuhnya dapat direproduksi.
  2. Fase non-deterministik. Jalankan pipenv update dan kemudian jalankan tes, sehingga ia menarik yang terbaru dari semua dependensi Anda (yang pada dasarnya sama dengan perilaku tanpa lockfile, saya pikir?).

@tsiq-oliverc Untuk mendapatkan build deterministik, saya akan memikirkan pengaturan berikut:

  • membangun pekerjaan cache pypi: dijalankan sekali waktu, menghasilkan beberapa bentuk cache indeks pypi (sebagai direktori file atau yang serupa)
  • tugas pengujian perpustakaan: menggunakan cache pypi, tetapi menghindari pipenv

Menggunakan pipenv untuk melakukan penginstalan mirip dengan apa yang harus dilakukan oleh penginstalan perpustakaan itu sendiri tetapi jelas berbeda karena kode yang berbeda melakukan pekerjaan.

membangun pekerjaan cache pypi

$ git clone <repo_url> <project_dir>
$ cd <project_dir>
$ pip install pipenv
$ $ # clean pypi cache and make it ready to cache somehow - not described here
$ pipenv install -e .[test]
$ # if we need extra testing packages in pipenv
$ pipenv install <extra_test_packages>
$ # record current requirements expressed in `Pipfile.lock`
$ pipenv lock
$ # if needed, record the `Pipfile.lock` somewhere

Keluaran dari pekerjaan tersebut adalah:

  • Pipfile.lock sebagai dependensi yang tercatat (dapat membantu pengembang mereproduksi lingkungan dengan mudah)
  • cache pypi lokal yang sudah terisi sebelumnya

tugas pengujian perpustakaan

ada fase:

  • konfigurasikan lingkungan untuk memaksa tox , pip dll. hanya menggunakan cache pypi lokal kami
  • jalankan tes CI (hindari menggunakan pipenv )

apa yang kita dapatkan

  • perpustakaan diuji dalam lingkungan deterministik
  • perpustakaan diuji termasuk. itu kemampuan untuk menginstal sendiri sendiri
  • Pipfile.lock mencatat paket pypi yang digunakan untuk menginstal perpustakaan. Ini dapat digunakan untuk mereproduksi lingkungan di situs pengembang.
  • adaptasi ke paket yang ditingkatkan pada (mungkin eksternal) pypi sederhana (jalankan kembali pekerjaan "build pypi cache) dan dilakukan dengan cara yang terkontrol (konten pypi dicatat termasuk hash)

Keuntungan lainnya adalah, pengaturan ini tidak mengharuskan pengembang mempertahankan Pipfile atau Pipfile.lock . Juga menjalankan tes dalam konteks yang berbeda selalu sama ( Pipfile.lock selalu dibangun kembali dalam konteks tertentu).

Apa yang masih hilang (dan bisa dilakukan)

Cache pypi adalah bagian yang membutuhkan penelitian. Saya kira, direktori sederhana sudah cukup dan mungkin pipenv sudah siap membantu dengan itu. Mungkin masalah #1731 adalah bagian yang hilang.

Sebagai paket yang melakukan resolusi dependensi, banyak pengujian kami sendiri mengandalkan build deterministik — yaitu, mengambil hal-hal yang diketahui dan mengharapkan grafik yang diselesaikan. Kami menggunakan pytest-pypi untuk ini.

Suka diskusi yang hidup tentang topik ini. Saya pikir nuansa itu penting dan Anda harus selalu menguji terhadap dependensi yang diketahui serta yang tidak disematkan

anda harus selalu menguji terhadap dependensi yang diketahui serta yang tidak disematkan

Saya mendukung saran ini. Sebaiknya selalu memiliki "status baik yang diketahui" eksplisit untuk build yang dapat direproduksi dan untuk menyederhanakan proses debug jika pembaruan merusak sesuatu selain memastikan bahwa versi minor/perbaikan bug yang lebih baru juga berfungsi.

(Menurut pendapat saya yang sangat pribadi, situasi yang ideal adalah manajer paket menginstal versi minor terbaru secara default sehingga perpustakaan selalu dapat menentukan versi ketergantungan konkret yang mereka uji, tetapi saya menyadari itu adalah pendapat yang sangat kontroversial dan mengharuskan semua orang untuk mengikuti semver.)

@Moritz90 @techalchemy @uranusjr @tsiq-oliverc

Berikut ringkasan saya dari diskusi sebelumnya.

Masalah khusus dan solusi yang diusulkan

Banyak konteks eksekusi - siapa yang akan memelihara file Pipfile.lock ?

Setiap penerjemah OS dan python yang didukung berkontribusi pada matriks kemungkinan konteks eksekusi.

Misalnya Flask mendukung (setidaknya hal-hal CI terlihat di repositori):

  • OS Windows (python 2.7 dan Python 3.6)
  • Linux (python 2.7, 3.4, 3.5, 3.6, nightly, pypi)
  • OSX (py - tidak yakin apakah ada lebih banyak versi)

Itu membuat 9 konteks eksekusi berbeda yang mungkin berbeda.

Setiap konteks eksekusi mungkin memiliki Pipfile.lock .

Siapa yang akan memelihara mereka?

Pilihannya adalah:

  • Biarkan pengembang melakukannya secara manual (TIDAK ADA CARA)
  • Pertahankan hanya satu Pipfile.lock untuk platform pengembangan utama (platform mana yang suka diabaikan?)
  • Otomatisasi pembuatan melalui CI (YA)

Proposal: Biarkan CI menghasilkan file dengan pipenv install -e . . Jangan sertakan dalam repo, bantu pengembang untuk memilih Pipfile.lock sebagai hasil dari pembuatan otomatis.

Pengembang membutuhkan lingkungan yang dapat diprediksi

Saat memperbaiki masalah, yang mungkin disebabkan oleh perubahan dependensi pada pypi, pengembang mungkin memerlukan cara sederhana untuk mereproduksi lingkungan dari pengujian yang gagal.

Usul:

  • untuk banyak paket, perubahan dependensi pypi sangat jarang terjadi, sehingga bukan masalah nyata
  • untuk memperbaiki lingkungan sendiri, pengembang dapat menghasilkan Pipfile.lock oleh pipenv install -e . diikuti oleh pipenv lock .
  • untuk mereplikasi lingkungan dari pengujian yang gagal, pengembang memilih Pipfile.lock dari pengujian yang gagal.
  • todo: tunjukkan contoh, cara menerapkan Pipfile.lock di tox.ini .

CI harus mengungkapkan setup.py broken yang rusak

Pustaka setup.py mungkin rusak (ketergantungan yang hilang pada install_requires , penentu versi tidak ada, dll.) dan pengujian CI tidak boleh menyembunyikan masalah seperti itu (dengan melakukan prainstal dependensi yang dihilangkan sendiri).

Usul:

  • percaya pipenv install -e . untuk memberikan hasil yang sama seperti instalasi biasa (saat ini ada beberapa masalah dengan itu).
  • jalankan tes instalasi biasa (tanpa pipenv ) dan mungkin bandingkan output pip freeze dihasilkan adalah subset dari apa yang diinstal oleh pipenv .

Ketergantungan pypi yang diperbarui dapat merusak banyak hal, CI akan mendeteksi pengejaran seperti itu

Beberapa pembaruan ketergantungan dapat merusak perpustakaan yang menggunakannya. CI akan mendeteksi kegagalan pada masalah tersebut.

Usul:

  • setidaknya satu tes harus dijalankan terhadap versi yang tidak dipasangi pin
  • jika CI selalu menghasilkan Pipfile.lock , ini bukan masalah (karena kami tetap menjalankan dalam mode yang tidak disematkan)

Mode CI untuk berbagai jenis perpustakaan

Dalam semua mode yang diusulkan, saya mencoba untuk menghindari menyimpan file pipenv di repositori untuk menyelamatkan pengembang dari mempertahankan hal-hal yang sangat rumit ini (otomatisasi!!!).

Berbeda dengan teks asli saya, mode ke-2 dan ke-3 memang menggunakan pipenv dalam skrip CI.

Mode: Lari, Forrest, Lari!

Paket sederhana dengan jumlah dependensi yang lebih kecil yang tidak sering berubah.

Jalankan saja seperti sebelum era pipenv dan buat semuanya tetap sederhana bagi kami.

Kasus yang jarang terjadi ketika dependensi akan membuat masalah mudah diperbaiki dan tidak membuat CI menjadi lebih kompleks.

Mode: Hasilkan dan segel

Setiap kali pengujian CI dijalankan, buat Pipfile.lock yang sepenuhnya menggambarkan lingkungan yang digunakan saat ini.

Pipfile.lock akan menjadi artefak CI.

Jika ada yang salah, pengembang dapat memilih Pipfile.lock dari build yang rusak, menerapkannya secara lokal dan melakukan pengujian dan perbaikan.

Jika seseorang ingin men-deploy, Pipfile.lock dari build terakhir yang berhasil dapat digunakan.

Mode: Zaman Es

Ketika mengubah dependensi adalah masalah nyata, CI akan membuat Pipfile.lock sekali waktu dan tetap menggunakannya untuk periode tertentu (sebulan?).

Ini membuat pengaturan CI lebih sulit, karena harus ada setidaknya dua pekerjaan yang berbeda (satu menghasilkan Pipfile.lock , yang lain menerapkannya dan menggunakan dalam pengujian).

Peringatan: Pipfile.lock harus diperbarui saat ini, setup.py mengubah dependensi.

Perhatikan, bahwa Zaman Es membutuhkan tes jenis tupai Scrat yang mengabaikan status beku dan memeriksa versi yang tidak disematkan.

Kata penutup

Seperti yang terlihat, determinisme dan kompleksitas tumbuh mode demi mode.

Proposal saya akan menjadi:

  • mulai sederhana ("Jalankan, Forrest, Jalankan"). Anda mendapatkan efisiensi dan kecepatan.
  • jika semuanya menjadi terlalu rumit karena perubahan dependensi, lanjutkan ke "Hasilkan dan segel". Anda mendapatkan pengulangan di lingkungan lokal.
  • jika semuanya benar-benar buruk, buka mode "Zaman Es". Anda mendapatkan determinisme (sementara).

Semua keuntungan membutuhkan sesuatu.

Jika tujuannya di sini adalah untuk memperbarui saran di dokumen, maka jujur ​​rasanya tidak bertanggung jawab untuk mengatakan sesuatu yang sangat berbeda dengan "Ikuti praktik terbaik (bangunan yang dapat direproduksi) secara default, sampai Anda tidak punya pilihan."

@vlcinsky Di bawah judul "Mode: Generate and seal", mungkin masuk akal untuk menyebutkan bahwa Pipfile.lock berhasil terakhir harus selalu disimpan, misalnya dengan mendeklarasikannya sebagai artefak Jenkins. Dengan perubahan itu, tidak masalah untuk merekomendasikan pengaturan itu untuk sebagian besar proyek. Seperti @tsiq-oliverc, saya tidak akan merekomendasikan mode pertama.

Semakin saya memikirkannya, semakin saya merasa bahwa dokumentasi ini akan menjadi bagian mengapa menggunakan pipenv untuk pembuatan CI adalah ide yang bagus, bahkan jika Anda sedang mengembangkan perpustakaan.

@tsiq-oliverc sebagian besar paket python umum berada dalam mode "Jalankan, Forrest, Jalankan". Saya telah membantu beberapa paket ini dengan memperkenalkan tox dan pytest , karena saya merasa itu akan berkontribusi pada kualitas paket yang diberikan dan karena saya memiliki gagasan yang cukup jelas, bagaimana hal itu dapat dilakukan dengan baik.

Sekarang ada alat hebat lainnya dan saya bertanya-tanya bagaimana cara menggunakan pipenv dengan benar dalam proyek python umum untuk berkontribusi pada kualitasnya. Saya ingin menemukan satu atau dua resep yang bekerja dengan baik yang dapat dibenarkan dan mudah diikuti.

Apa yang akan saya katakan pada proyek Flask?

  1. Ikuti praktik terbaik (build yang dapat direproduksi) secara default, hingga Anda tidak punya pilihan?
  2. Tambahkan 9 file Pipfile.lock dan siapkan kebijakan untuk memperbaruinya?
  3. Memfaktorkan ulang skrip CI untuk Travis dan Appveyor agar berfungsi dalam dua fase mengikuti mode Zaman Es?
  4. Ubah skrip CI untuk Travis dan Appveyor untuk menghasilkan artefak Pipfile.lock untuk kasus, ketika seseorang perlu mereproduksi tes yang gagal di komputernya sendiri?
  5. tidak ada komentar, selain dari "Terima kasih banyak untuk Flask."

Tujuannya adalah untuk menemukan gaya kerja yang fungsional. Jika berakhir di doc, bagus, jika tidak, tidak masalah.

@vlcinsky saya akan mengatakan (1) dan (4) harus menjadi rekomendasi untuk proyek semacam itu. Meskipun tanpa Pipfile.lock Anda tidak akan mengetahui versi yang digunakan dalam pembuatan sebelumnya (yang baik-baik saja di luar lingkungan perusahaan), Anda masih akan mendapatkan hasil yang dapat direproduksi jika Anda membuat dan mengarsipkan file kunci selama membangun.

Sunting : Versi tl;dr dari rekomendasi saya adalah:

  • Selalu pastikan build Anda dapat direproduksi, terlepas dari apakah Anda sedang mengembangkan library atau aplikasi. pipenv dapat membantu Anda mencapai tujuan ini.
  • Jika Anda sedang mengembangkan aplikasi, komit Pipfile.lock ke repositori Anda dan gunakan untuk penerapan. (Ini sudah dicakup oleh dokumentasi yang ada.)
  • Jika Anda mengembangkan pustaka sumber terbuka, buat Pipfile.lock on-the-fly di build CI Anda dan arsipkan untuk nanti.
  • Jika Anda mengembangkan pustaka dan bekerja di lingkungan perusahaan yang terbatas, pertahankan jumlah file kunci yang sesuai dan gunakan yang ada di build CI Anda.

(Tentu saja, dokumentasi yang sebenarnya harus memiliki sedikit lebih banyak detail dan contoh.)

@ Moritz90 Saya memodifikasi "Hasilkan dan Segel" seperti yang Anda usulkan.

Re (1): mudah diucapkan, tidak mungkin dijalankan tanpa lebih spesifik.

Re (4): ya, saya juga berpikir, bahwa "Generate and Seal" adalah mode yang paling layak. Tapi dalam kasus Flask saya tidak akan berani (setidaknya tidak untuk saat ini).

Pipfile.lock di lingkungan perusahaan: Itu harus dibuat entah bagaimana, baik (semi) secara manual atau otomatis. Saya kira, di lingkungan perusahaan Anda tidak menginstal langsung dari pypi publik tetapi menggunakan beberapa yang pribadi dan yang hanya menyediakan paket yang disetujui ( devpi-server menyediakan layanan hebat dalam hal itu - banyak indeks, volatilitas terkontrol dari paket yang diterbitkan, persetujuan untuk eksternal paket dll.) Jika proses membangun Pipfile.lock berjalan di lingkungan seperti itu, itu hanya dapat menggunakan apa yang disetujui jadi jika versi baru akan muncul di sana, seseorang harus berdiri dan membuatnya disetujui. Mengikuti CI build akan menguji bahwa itu tidak merusak sesuatu. Dan dengan pipenv check pengujian masalah keamanan mungkin juga otomatis.

Saya kira alur kerja seperti itu akan lebih aman dibandingkan dengan seseorang yang membuatnya (semi) secara manual. Tetapi pengetahuan saya tentang lingkungan perusahaan sangat terbatas.

Halo tim pipenv. Saya membagikan banyak dari apa yang dikatakan dalam teks ini, ini sangat membantu pengembang mana pun untuk lebih memahami batasan Pipfile/pipenv ketika mengembangkan perpustakaan. Saya ingin melihat teks ini atau bagian dari teks ini terintegrasi di dalam dokumentasi pipenv resmi.

Saya memiliki amandemen berikut yang ingin saya diskusikan:

Untuk paket python internal kami, sepenuhnya dapat digunakan kembali, dipublikasikan di pypi internal kami, dll, dan bahkan untuk paket python saya sendiri (mis: cfgtree , txrwlock , pipenv-to-requirements ), saya menggunakan paket yang mungkin sudah diketahui atau bahkan digunakan beberapa orang , yang mengabstraksi detail ini dan membuat hidup pengembang python lebih mudah: PBR.
PBR pada dasarnya membaca requirements.txt ditemukan di folder root dari paket distribusi dan memasukkannya ke dalam install_requires dari setup.py . Pengembang hanya perlu mempertahankan requirements.txt dengan deklarasi ketergantungan yang longgar. Sampai dukungan Pipfile terintegrasi secara resmi di dalam PBR, saya harus menggunakan pipenv-to-requirements yang secara otomatis menghasilkan requirements.txt dari Pipfile sehingga keduanya disinkronkan dan keduanya di-commit di sumber, dan PBR melakukan injeksi dengan benar setelah paket distribusi dibangun. Saya pikir seseorang dapat menggunakan pipenv untuk menghasilkan requirements.txt

Saya bekerja pada dukungan Pipfile untuk PBR, sehingga akan dapat membaca Pipfile (dan bukan file kunci) dan menyuntikkannya ke install_requires seperti halnya dengan requirements.txt .

Saya tidak tahu apakah ada paket serupa lainnya, karena itu juga melakukan hal-hal lain yang mungkin tidak diinginkan orang (versi dari riwayat git, pembuatan otomatis PENULIS dan ChangLog).

Tetapi pada akhirnya, saya benar-benar merasa lebih mudah untuk menulis, memelihara, dan menangani versi perpustakaan Python, saya akan sedih untuk tidak membagikan pengalaman ini. Saya mempromosikannya sebagai cara "disarankan" untuk menulis perpustakaan python modern di perusahaan saya.

Saya rasa itu seperti "curang" pada semua kesulitan tentang perpustakaan dan pipenv, tetapi pada akhirnya pekerjaan selesai dan pengembang senang menggunakannya sejauh ini. Bagian dari pelatihan python, saya berikan kepada pengembang python baru di perusahaan saya, melibatkan, pertama-tama menulis perpustakaan python yang memelihara install_requires secara manual, dan kemudian beralih ke PBR untuk melihat bagaimana itu menjadi lebih mudah ( dan sejujurnya saya adalah penggemar fitur komit semantik pbr untuk secara otomatis membuat tag versi semver yang tepat).

Bagian dari alasan untuk mendeklarasikan dependensi perpustakaan menggunakan file khusus juga untuk perpustakaan adalah untuk dapat menggunakan alat seperti readthedocs atau pyup (bahkan jika pyup lebih masuk akal ketika ditautkan ke aplikasi).

Saya tidak selalu ingin mempromosikan metode ini sebagai cara "standar" dalam melakukan paket python, ini sebenarnya adalah cara "OpenStack", tetapi saya akan membagikan pengalaman saya, dan jika orang lain memiliki pengalaman yang serupa atau bertentangan, saya akan senang mendengar mereka dan memperbarui sudut pandang saya.

Tim, apa pendapat Anda tentang semacam bagian "komunitas" pada dokumentasi? Agar pengguna seperti saya dapat berbagi pengalamannya tentang bagaimana dia menggunakan pipenv, tanpa harus mendapat dukungan penuh dari tim pipenv?

PS: Saya dapat memindahkan ini ke masalah khusus jika Anda tidak ingin mencemari utas ini

@vlcinsky (1) sangat mudah dijalankan - letakkan file kunci Anda di repo Anda.

Saya pikir apa yang Anda maksud adalah: tidak mungkin memberikan saran khusus setelah strategi dasar ini tidak lagi memadai. Itu memang benar, tapi itu karena masalah spesifik mungkin berbeda berdasarkan kasus per kasus.

Atau dengan kata lain, solusinya bergantung pada jaminan tambahan apa yang Anda inginkan untuk diberikan oleh alur kerja CI Anda.

@gsemet tau pbr - ini benar-benar hebat. Dan saya mengikuti upaya Anda untuk mendukung Pipfile di pbr kapan pun saya bisa (beberapa jempol, suara dll).

Dalam kasus masalah ini (mencari pola pipenv dan antipatterns untuk pustaka python umum) saya sengaja menghilangkan pbr karena dua alasan:

  • itu akan membuat diskusi konseptual lebih kompleks
  • beberapa orang tidak menyukai pbr karena alasan lain (Anda menyebutkannya) dan mungkin akan mengalihkan diskusi

Di sisi lain, saya sangat menantikan resep Anda untuk pbr-lovers. Saya akan membacanya.

@tsiq-oliverc Anda berhasil: letakkan file kunci

Ini adalah persis masalah yang memotivasi saya untuk memulai masalah ini. Jika Anda membaca ulang awal masalah ini, Anda akan menemukan deskripsi dari beberapa kasus, di mana menambahkan Pipfile.lock dapat merusak pengujian CI Anda (baik merusak proses build atau menyembunyikan masalah, yang seharusnya terdeteksi, atau menginstal dependensi yang salah untuk konteks tertentu...).

Jika Anda menunjukkan kepada saya repo, di mana ini dilakukan dengan benar (perpustakaan python umum), saya akan senang. Atau saya akan menunjukkan, risiko apa yang ada atau hal-hal apa yang belum selesai.

Dingin ! Saya juga memelihara cookiecutter ini :)

@vlcinsky Benar, jadi mari kita

Sejauh yang saya tahu, ini adalah gejala spesifik di posting asli Anda:

  • Menyembunyikan dependensi setup.py yang rusak. Ini terdengar seperti bukan masalah - pipenv install -e . , bukan?
  • Ketergantungan cenderung tidak valid untuk versi python yang berbeda atau di OS lain. Saya dapat melihat bahwa ini bisa menjadi masalah, tetapi dapatkah Anda memberikan contoh nyata tentang di mana hal ini penting dalam praktik? (dalam konteks file kunci)
  • Pengembang dipaksa untuk memperbarui ... ketika perpustakaan lain diperbarui dan mungkin dapat digunakan di dalam perpustakaan. Mereka tidak dipaksa untuk melakukan itu. Mereka melakukan itu jika mereka ingin memberikan jaminan bahwa perpustakaan mereka bekerja melawan versi n+1 daripada versi n dari ketergantungan mereka. Tetapi perhatikan bahwa saya sudah mengusulkan alternatif yang memberikan yang terbaik dari kedua dunia.
  • Bersaing dengan Tox. Saya tidak tahu apa-apa tentang Tox. Tapi ya, menggunakan dua alat secara bersamaan untuk mengelola dependensi Anda terdengar seperti resep bencana. Saya akan mengatakan gunakan mana yang lebih unggul untuk tugas tertentu itu.
  • Pipenv gagal. Ini terdengar seperti bukan masalah lain - Anda bisa menyematkan versi Pipenv (itu solusi saya saat ini, sama seperti saya menyematkan gambar Docker saya, versi Pip saya, dll.)

@tsiq-oliverc Saya harus mengatakan, komentar Anda menginspirasi saya dan saya tahu mereka berkontribusi pada tingkat reproduktifitas yang lebih tinggi dari solusi yang diusulkan.

Berikut ini terkait dengan proposal Anda untuk menempatkan lockfile ( Pipfile.lock ) ke dalam repo untuk memastikan pengulangan:

re Menyembunyikan dependensi setup.py yang rusak. . pipenv install -e . mengikuti apa yang saya usulkan, tetapi perhatikan, bahwa ini bukan penggunaan Pipfile.lock , ini adalah metode untuk (kembali) membuatnya. Jika seseorang menyimpan Pipenv.lock dan menggunakannya untuk membuat virtualenv sebelum menginstal paket, masalahnya ada.

re Ketergantungan cenderung tidak valid untuk versi python yang berbeda atau di OS lain . Contohnya banyak: doit diinstal untuk Python 2.7 harus versi yang lebih lama karena yang lebih baru menjatuhkan dukungan untuk Python 2.x. Ketergantungan watchdog memerlukan pustaka yang bergantung pada platform: inotify di Linux, sesuatu yang lain di Windows, sesuatu yang lain di OSX. Mantan klien saya biasa mengatakan "Ini tidak akan pernah terjadi" dan dalam 50% situasi itu terjadi dalam 2 minggu. Ini bukan praktik terbaik untuk skrip CI.

re Pengembang dipaksa untuk memperbarui .. Bayangkan perpustakaan Open Source dengan 15 kontributor. Sangat mudah untuk melupakan regenerasi Pipfile.lock oleh pendatang baru atau pengembang inti yang lelah. Misalnya dalam paket maya saya diminta untuk membuat ulang Pipfile.lock karena ketergantungan baru ditambahkan ke setup.py . Apakah itu perlu? Apakah saya memperbaruinya dengan benar? Apakah saya memperbaruinya untuk semua konteks eksekusi yang didukung? Jawabannya tidak, tidak yakin, tidak. Bagaimanapun, terima kasih atas proposal Anda (itu mengilhami saya untuk solusi yang dijelaskan di sebelah komentar Anda).

re Bersaing dengan tox : Tox memungkinkan pembuatan beberapa virtualenvs dan otomatisasi menjalankan tes di dalamnya. Khas tox.ini mendefinisikan virtualenvs berbeda untuk python 2.7, 3.4, 3.5, 3.6 dan lainnya yang Anda butuhkan, dan memungkinkan menginstal paket di sana dan menjalankan test suite. Hal ini didirikan powertool penguji serius. pipenv bukan alat untuk tujuan ini, tetapi dapat mengganggu dalam menginstal hal-hal yang diperlukan. Di satu sisi saya mengikuti saran Anda dan mengusulkan untuk menggunakan alat superior (tox) di atas pipenv jika memungkinkan.

kembali Pipenv gagal. Ini sangat disayangkan. Saya memiliki tes CI (berbasis tox) yang berjalan dengan baik di localhost, tetapi ketika dijalankan melalui Travis, gagal karena masalah pipenv . Jika saya ingin menggunakannya sekarang, menyematkan tidak membantu sampai perbaikan dirilis. Tapi beginilah kelanjutannya - saya akan menunggu.

Perhatikan, bahwa beberapa bagian dari posting asli saya harus diperbarui seperti yang terlihat, menggunakan pipenv dalam skrip CI memiliki tempat yang dibenarkan (konfigurasi virtualenv "menyegel" untuk kemungkinan penggunaan nanti).

@tsiq-oliverc Sementara saya awalnya menyukai saran Anda untuk menguji baik "yang dikenal baik" dan versi terbaru, saya merasa semakin sulit untuk membenarkan upaya semakin saya memikirkannya. Saya pikir Anda harus memutuskan untuk melakukan salah satu atau yang lain, bukan keduanya.

Satu-satunya hal yang Anda dapatkan adalah Anda akan segera mengetahui apakah kegagalan disebabkan oleh pembaruan ketergantungan atau perubahan kode. Tetapi Anda dapat mencapai hal yang sama hanya dengan membuat komit terpisah (saat memperbarui dependensi yang dikunci secara manual) atau mencoba mereproduksi bug dengan file kunci terbaru yang dihasilkan oleh build yang berhasil (bila selalu menggunakan versi terbaru). Dan di lingkungan terbatas, Anda tidak bisa "hanya memperbarui" ...

@vlcinsky Sementara saya setuju dengan poin umum Anda tentang perbedaan antara lingkungan, argumen "satu file kunci per konfigurasi" terdengar seperti orang jerami bagi saya. Dalam praktiknya, Anda akan dapat berbagi file kunci di antara setidaknya beberapa lingkungan.

Satu pertanyaan terbuka yang tersisa yang belum dijawab siapa pun adalah bagaimana menangani kasus di mana Anda berdua perlu menguji di lingkungan yang berbeda dan mengunci dependensi Anda. Saya harus mengakui bahwa saya tidak tahu apa-apa tentang tox selain itu ada, tetapi sepertinya ada kebutuhan untuk semacam lem antara tox dan pipenv yang memecahkan masalah ini entah bagaimana.

@Moritz90

Bertemu dengan manusia jerami

Mengenai terlalu banyak varian Pipfile.lock berfungsi sebagai straw man (untuk menjauhkan orang lain dari bidang saya):

Labu

Saya mengambil proyek flask (menganggapnya sangat matang) dan menjalankan tes tox:

Di sini Anda melihat daftar varian yang diuji (hanya secara lokal di Linux, kalikan dengan 3 karena windows dan OSX akan melakukan serangkaian pengujian yang sama tetapi dapat menghasilkan lingkungan yang berbeda).

Ada 16 tes berbeda yang dijalankan pada satu OS, 5 di antaranya gagal karena saya tidak menginstalnya (tidak apa-apa), satu berurusan dengan membangun dokumen (membutuhkan perpustakaan yang dapat diimpor) dan satu lagi cakupan (yang juga membutuhkan perpustakaan yang dapat diimpor ):

  coverage-report: commands succeeded
  docs-html: commands succeeded
  py27-devel: commands succeeded
  py27-lowest: commands succeeded
  py27-simplejson: commands succeeded
  py27: commands succeeded
  py35: commands succeeded
  py36-devel: commands succeeded
  py36-lowest: commands succeeded
  py36-simplejson: commands succeeded
  py36: commands succeeded
ERROR:   py34: InterpreterNotFound: python3.4
ERROR:   pypy-devel: InterpreterNotFound: pypy
ERROR:   pypy-lowest: InterpreterNotFound: pypy
ERROR:   pypy-simplejson: InterpreterNotFound: pypy
ERROR:   pypy: InterpreterNotFound: pypy

Untuk setiap virtualenv yang dibuat, saya telah membuat file requirements.txt oleh pip freeze > {venv_name}.txt

Kemudian dihitung hash untuk file-file tersebut, diurutkan menurut nilai hash, sehingga semua sama akan dikelompokkan. Ini dia si manusia jerami:

b231a4cc8f30e3fd1ca0bfb0397c4918f5ab5ec3e56575c15920809705eb815e  py35.txt
b231a4cc8f30e3fd1ca0bfb0397c4918f5ab5ec3e56575c15920809705eb815e  py36.txt
cdf69aa2a87ffd0291ea65265a7714cc8c417805d613701af7b22c8ff2b5c0e4  py27-devel.txt
dfe27df6451f10a825f4a82dfe5bd58bd91c7e515240e1b102ffe46b4c358cdf  py36-simplejson.txt
e48cd24ea944fc9d8472d989ef0094bf42eb55cc28d7b59ee00ddcbee66ea69f  py36-lowest.txt
f8c745d16a20390873d146ccb50cf5689deb01aad6d157b77be203b407e6195d  py36-devel.txt
053e107ac856bc8845a1c8095aff6737dfb5d7718b081432f7a67f2125dc87ef  docs-html.txt
45b90aa0885182b883b16cb61091f754b2d889036c94eae0f49953aa6435ece5  py27-simplejson.txt
48bd0f6e66a6374a56b9c306e1c14217d224f9d42490328076993ebf490d61b5  coverage-report.txt
564580dad87c793c207a7cc6692554133e21a65fd4dd6fc964e5f819f9ab249c  py27.txt
8b8ff4633af0897652630903ba7155feee543a823e09ced63a14959b653a7340  py27-lowest.txt

Yang menakutkan, bukan? Dari semua tes, hanya dua yang berbagi dependensi beku yang sama.

Ini adalah kenyataan dari pustaka python umum dengan rangkaian pengujian yang baik. Anda sekarang mungkin akan mengakui, ini adalah sesuatu yang sangat berbeda dari pustaka python yang diuji di lingkungan perusahaan.

Jinja2

Memeriksa jinja2 , yang tampaknya merupakan binatang yang jauh lebih sederhana:

  coverage-report: commands succeeded
  py26: commands succeeded
  py27: commands succeeded
  py33: commands succeeded
  py35: commands succeeded
  py36: commands succeeded
ERROR:   docs-html: commands failed
ERROR:   py34: InterpreterNotFound: python3.4
ERROR:   pypy: InterpreterNotFound: pypy

Melihat checksum, saya terkejut, bahwa py27.txt dan py26.txt berbeda:

047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py26.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py33.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py35.txt
047a880804009107999888a3198f319e5bbba2fa461b74cfdfdc81384499864e  py36.txt
48bd0f6e66a6374a56b9c306e1c14217d224f9d42490328076993ebf490d61b5  coverage-report.txt
743ad9e4b59d19e97284e9a5be7839e39e5c46f0b9653c39ef8ca89c7b0bc417  py27.txt

@vlcinsky Itu memang menakutkan. Saya bertanya-tanya apakah Flask adalah kasus khusus atau apakah itu benar-benar norma, tetapi Anda pasti telah membuktikan bahwa saya salah.

Saya sekarang berharap perpustakaan Python kami tidak akan mengalami masalah yang sama suatu hari nanti dan perbedaannya akan lebih mudah dikelola di sana.

@Moritz90 Pustaka internal Anda melayani audiens yang sama sekali berbeda sehingga Anda dapat menjaga konteks eksekusi jauh lebih sempit.

Pustaka python umum seringkali fleksibel dan dapat dikonfigurasi, misalnya Flask memungkinkan parser json alternatif untuk diinstal dan menggunakan apa yang dicakup oleh uji coba terpisah.

Seseorang dapat belajar banyak tentang pengujian dan tox dari tox.ini Flask

varian pengujian terendah berhati-hati untuk menguji terhadap versi ketergantungan tertua.

devel sedang menguji versi pengembangan dependensi inti.

Saya akan mengatakan, Flask berada pada tingkat kompleksitas yang lebih tinggi dan menunjukkan rangkaian pengujian yang cermat.

tox.ini piramida menunjukkan jumlah lingkungan yang serupa (mereka juga bertujuan untuk cakupan kode 100%).

tox.ini maya sangat segar (2 hari) dan sederhana, bahkan di sini ada 4 lingkungan berbeda dan py27 berbeda dalam persyaratan beku dari py35 dan py36.

@Moritz90
Mengenai lem antara pipenv dan tox

  • pipenv --man menunjukkan beberapa instruksi, cara menggunakan pipenv dalam perintah tox.ini
  • tox-pipenv mencoba memberikan beberapa integrasi tambahan tetapi saat ini membingungkan saya.

File tox.ini memungkinkan menjalankan perintah arbitrer jadi ini termasuk pipenv .

pipenv memiliki fitur hebat, yang ketika dijalankan di virtualenv yang sudah diaktifkan (apa yang terjadi dalam tes berbasis tox), ia menginstal ke dalam virtual env yang diberikan. Ini sangat bagus.

Karena kita mungkin perlu Pipfile.lock dihasilkan, beberapa upaya ekstra harus dilakukan untuk mendapatkannya dan pindah ke tempat yang tepat (ag ke .tox/py36/Pipfile.lock untuk mencegah penimpaan dengan mengikuti tes. Ini mungkin, tetapi beberapa penyederhanaan akan diterima Mungkin beberapa trik dengan variabel lingkungan untuk lokasi Pipfile akan membuatnya lebih sederhana.

@vlcinsky

  • setup.py - Masih tidak yakin saya mengerti masalahnya. Anda menjalankan pipenv install -e . sekali sehingga setup.py sekarang dilacak melalui file kunci Anda. Dan kemudian jalankan pipenv install setiap kali Anda menambahkan paket baru ke setup.py.
  • Pengembang lupa memperbarui lockfile - pipenv --deploy dirancang untuk menangkap ini. Jalankan di CI Anda!
  • Pipenv gagal - setuju, jika ada bug di alat, itu menyebalkan. Tetapi bug umumnya diperbaiki. Itu bukan alasan untuk membuang seluruh filosofi
  • racun

    • Jika Tox bagus untuk mengelola tes, itu bagus. Jika itu juga bagus untuk mengelola paket dan build deterministik , itu lebih baik lagi.

    • Tetapi jika itu benar, tidak akan ada alasan bagi Pipenv untuk ada. Jadi saya hanya bisa berasumsi ada semacam batasan dengan Tox.

    • Sama halnya dengan di atas, keadaan dunia saat ini (kurangnya interop yang baik) sepertinya bukan alasan untuk menolak filosofi tersebut.

  • Beberapa env

    • Jelas bahwa setidaknya ada beberapa kasus khusus di sini, seperti Flask.

    • Saya tidak memiliki saran yang lebih baik bahwa banyak file kunci (walaupun mungkin ada fitur masa depan untuk Pipenv dalam hal ini?)

    • Tetapi bahkan dalam kasus ini, saya masih tidak yakin bahwa mengelola banyak file kunci adalah masalah dalam praktiknya. Kasus terburuk, tampaknya Anda dapat membuat skrip sederhana update-all-lockfiles.sh secara lokal, dan menjalankan pipenv --deploy pada CI Anda untuk mendeteksi kesalahan.


@Moritz90 - Setuju, pendekatan "dua fase" mungkin berlebihan dalam banyak kasus. Secara khusus, jika Anda membuat pembaruan "manual" yang disengaja/disengaja ke file kunci Anda, itu sama sekali tidak perlu.


Secara lebih umum, akan lebih baik untuk memastikan "proposal" ini berfokus pada hal-hal yang sebenarnya merupakan masalah sulit (dalam pandangan saya, itu (A) melayani banyak envs, (B) ingin menangkap perubahan dalam dependensi hulu). Seharusnya tidak didasarkan pada hal-hal sementara (bug di Pipenv) atau potensi kesalahpahaman tentang bagaimana alat ini dimaksudkan untuk digunakan.

Tetapi bahkan untuk masalah "sulit" itu, pembingkaian harus seperti "dalam beberapa kasus tepi yang kompleks, Anda mungkin menemukan bahwa alur kerja Pipenv dasar tidak mencukupi, jadi inilah beberapa hal yang perlu dipikirkan". IMO, itu tidak boleh dibingkai sebagai pendekatan default (karena kebanyakan orang tidak akan memiliki masalah itu).

Contoh dokumentasi yang diberikan @vlcinsky akan menjadi lebih sederhana dan tidak membingungkan jika Pipenv/Pipfile mengizinkan penanganan lib-dependencies , app-dependencies dan dev-dependencies . Dokumen dapat terlihat seperti ini:

Gunakan opsi lib-dependencies jika paket Anda adalah pustaka bersama. Contoh Pipfile :

[lib-dependencies]
some-lib=="*"
another-lib=="*"
yet-another-one==">=1.0"

[dev-dependencies]
some-dev-tool=="1.1"

Untuk pustaka bersama, penting untuk menjaga rentang versi di bawah [lib-dependencies] selebar mungkin, untuk mencegah konflik versi pada sistem konsumen.

Jika paket Anda adalah aplikasi (dimaksudkan untuk diinstal oleh pipenv pada sistem target) yang memerlukan versi ketergantungan yang tepat, Anda harus menggunakan opsi [app-dependencies] . Contoh Pipfile :

[app-dependencies]
some-lib=="1.0.12"
another-lib=="1.*"
yet-another-one=="2.0"

[dev-dependencies]
some-dev-tool=="1.1"

/Akhir contoh dokumen

Pendekatan lain bisa berupa Pipfile.lib dan Pipfile.app .

Saya pikir sesuatu seperti ini akan menghilangkan kebutuhan akan bagian anti-pola dan alat pihak ketiga untuk mengisi celah.

Menyebut alat pengemasan pipenv menyesatkan jika seseorang mengharapkannya untuk membuat pustaka python atau terlibat secara mendalam dalam pembuatannya.

Saya pikir ini adalah masalah nyata, yang menyebabkan banyak kebingungan. Terutama di antara orang-orang yang terbiasa dengan manajer paket dalam bahasa pemrograman lain (misalnya JS, Rust, Elm). Butuh beberapa bulan dan sesekali membaca masalah GIthub, sampai saya menyadari bahwa saya menggunakan Pipenv dan setup.py dengan cara yang salah.

@feluxe

[lib-dependencies] atau Pipfile.lib adalah apa yang kami miliki hari ini di Pipfile (sebagai dependensi abstrak - seluas mungkin).

[app-dependencies] atau Pipfile.app adalah apa yang kami miliki di Pipfile.lock (sebagai dependensi khusus).

pipenv dan filenya dapat digunakan dalam dua situasi berbeda - mengembangkan perpustakaan atau menyiapkan penerapan aplikasi tetapi mungkin tidak untuk keduanya sekaligus. Untuk alasan ini saya tidak melihat alasan kuat untuk menambahkan bagian tambahan ke Pipenv . Pengembang bertanggung jawab untuk mengetahui, jenis tujuan apa yang akan dilayani oleh Pipfile .

Saya pikir ini adalah masalah nyata, yang menyebabkan banyak kebingungan. Terutama di antara orang-orang yang terbiasa dengan manajer paket dalam bahasa pemrograman lain (misalnya JS, Rust, Elm). Butuh beberapa bulan dan sesekali membaca masalah GIthub, sampai saya menyadari bahwa saya menggunakan Pipenv dan setup.py dengan cara yang salah.

Sepakat. Solusi tiga bagian juga merupakan solusi yang sangat menarik yang belum pernah saya pertimbangkan, dan tampaknya benar dan (mengejutkan!) sederhana.

Berasal dari latar belakang Python sendiri, saya selalu merasa package.json Node melakukan kesalahan (Rust lebih baik karena memiliki kompiler dan tautan, dan dapat menyelesaikan ini di tahap selanjutnya). Memperlakukan dependensi aplikasi dan lib dengan cara yang sama tidak akan berfungsi untuk bahasa skrip seperti Python, setidaknya dalam arti abstrak—yaitu mungkin berhasil untuk Anda, tetapi alat generik seperti Pipenv tidak dapat melakukannya karena perlu umum.

Meskipun saya menyukai solusi tiga bagian dalam konsep, itu masih merupakan perubahan yang agak tidak sesuai dengan ekosistem yang ada. Sudah ada setup.py, setup.cfg, dan (berpotensi) pyproject.toml mengisi ruang ini. Jika Pipenv (Tepatnya Pipfile) ingin pindah ke luar angkasa, ia perlu berkonsolidasi dengan proyek terkait, seperti pip (dukungan perpustakaan idealnya didukung langsung olehnya) dan flit .

Seperti yang saya sebutkan dalam masalah lain tentang penanganan ketergantungan lib/aplikasi, diskusi ini perlu dieskalasi ke pypa-dev (milis) dan/atau proses PEP, sehingga dapat didengar lebih baik oleh pihak lain dan orang terkait, sebelum Pipenv (Pipfile) dapat bergerak ke segala arah.

@vlcinsky

[lib-dependencies] atau Pipfile.lib Anda adalah apa yang kami miliki saat ini di Pipfile (sebagai dependensi abstrak - seluas mungkin).

Maaf jika ini tidak jelas. lib-dependencies dimaksudkan untuk menjadi apa yang saat ini dimasukkan orang ke setup.py / install_requires . Mungkin pypi-dependencies akan menjadi nama yang lebih baik untuk apa yang saya maksud.

@uranusjr

Sudah ada setup.py, setup.cfg, dan (berpotensi) pyproject.toml mengisi ruang ini.

Pipenv (alat baris perintah) dapat menghubungkan setup.py . Hanya bagian ketergantungan setup.py harus dipindahkan ke Pipfile. Setidaknya dalam imajinasi saya :)

Seperti yang saya sebutkan dalam masalah lain tentang penanganan ketergantungan lib/aplikasi, diskusi ini perlu dieskalasi ke pypa-dev (milis) dan/atau proses PEP, sehingga dapat didengar lebih baik oleh pihak lain dan orang terkait, sebelum Pipenv (Pipfile) dapat bergerak ke segala arah.

Ok, maaf mengganggu ;) Jika saya menemukan waktu saya akan menulis sesuatu untuk milis.

Namun, dalam ruang lingkup proposal ini, saya menyarankannya untuk fokus pada praktik terbaik yang mungkin saat ini, alih-alih masuk ke lubang kelinci untuk mengerjakan alur kerja baru untuk seluruh komunitas pengemasan Python. Akan lebih produktif untuk mengusulkan praktik terbaik dalam batasan saat ini, dan kemudian memulai diskusi untuk perbaikan.

@uranusjr - Saya berasal dari latar belakang "terkompilasi", jadi saya ingin tahu mengapa ini terjadi?

Memperlakukan dependensi aplikasi dan lib dengan cara yang sama tidak akan berfungsi untuk bahasa skrip seperti Python

@tsiq-oliverc Karena praktik terbaik aplikasi mengharuskan Anda untuk menyematkan dependensi Anda, perpustakaan juga akan mulai menyematkannya, jika mereka menggunakan sumber file persyaratan yang sama. Ini akan menyebabkan masalah dalam resolusi ketergantungan.

Katakanlah aplikasi saya memiliki dua dependensi A dan B, keduanya bergantung pada C, tetapi A pin v1, sedangkan B pin v2. Bahasa yang dikompilasi memungkinkan rantai alat untuk mendeteksi ini pada waktu kompilasi, dan menyelesaikannya dengan banyak cara. Rust, misalnya, melakukan ini selama waktu penautan— Eksekusi akhir akan berisi dua salinan C (v1 dan v2), dengan A dan B yang terhubung ke masing-masing salinan tersebut. Di tanah C++ ini akan diselesaikan dengan perpustakaan dinamis; pencarian simbol dilakukan bahkan kemudian (saat runtime), tetapi idenya sama—kompiler mengetahui apa yang Anda butuhkan (dari antarmuka yang Anda gunakan), dan dapat bertindak sesuai dengan itu.

Bahasa skrip tidak dapat melakukan ini karena tidak tahu apa yang sebenarnya ingin Anda lakukan sampai benar-benar mencapai panggilan. Node mengatasi ini dengan selalu menganggap dependensi tidak kompatibel (A dan B selalu mendapatkan C mereka sendiri, bahkan jika dua salinan identik), tetapi itu mengarah ke kelas masalah baru, dan menghasilkan peretasan canggung seperti dependensi rekan yang semua orang (Saya harap?) setuju itu mengerikan. Python mungkin tidak ingin pergi ke sana (tidak bisa, karena itu kemungkinan akan merusak semua instalasi Python yang ada).

Cara lain untuk mengatasi ini adalah dengan melakukan sesuatu yang cerdas dalam alat pengemasan yang "melepaskan" versi ketergantungan. Bundler (dari Ruby) melakukan ini, dengan merekomendasikan orang untuk tidak memasukkan file kunci ke dalam permata, sehingga Bundler dapat menggunakan versi yang tidak disematkan di Gemfile, alih-alih versi yang disematkan di Gemfile.lock. Tetapi orang cenderung mengabaikan saran dan melakukan apa pun yang mereka inginkan, jadi Anda masih mendapatkan versi yang disematkan di mana-mana.

Saya mungkin agak terlalu kuat untuk mengatakan bahwa itu tidak akan berhasil . Tetapi setidaknya semua percobaan sebelumnya telah gagal, dan banyak dari mereka yang mencoba adalah orang-orang yang sangat pintar, jauh lebih pintar dari saya. Saya tidak berpikir ini dapat dilakukan, secara pribadi, dan saya akan terus berpikir seperti ini sampai saya melihat proposal yang sangat brilian yang benar-benar melakukannya.

@tsiq-oliverc Pieter Hintjens menulis di suatu tempat konsep "Komentar diterima dalam bentuk permintaan tarik"

Saya suka itu karena mengalihkan fokus dari nasihat filosofis ke hal-hal yang benar-benar nyata dan praktis. Dan itu juga membatasi jumlah komentar karena seorang komentator sering mengetahui bahwa ide tersebut tidak lengkap atau entah bagaimana rusak dalam penggunaan nyata.

Saya meminta Anda untuk contoh pustaka python, di mana pipenv digunakan dengan benar (atau setidaknya digunakan) dan Anda tidak memberikannya.

Anda mengomentari kualitas tox tetapi mengakui bahwa Anda tidak terbiasa dengannya, masih mengulangi sesuatu tentang praktik terbaik di dunia pengembangan paket python.

Anda mengatakan Flask mungkin merupakan kasus khusus. Jadi saya mencari Github untuk proyek python menggunakan Word "perpustakaan", diurutkan berdasarkan jumlah garpu (karena mungkin mencerminkan berapa banyak orang yang melakukan pengembangan dengannya), mengabaikan semua "daftar kurasi sesuatu" dan menghitung jumlah lingkungan untuk satu OS (biasanya Linux):

Jumlah sebenarnya dari lingkungan untuk menjalankan pengujian sebagian besar akan 2 (+Windows) atau 3 (+OSX) kali lebih tinggi.

tox digunakan dalam 2 proyek dari 3 (Saya tidak membandingkannya dengan Travis atau Appveyor karena mereka melakukan pengujian tingkat lain di samping).

Jumlah lingkungan untuk diuji agak tinggi, Flask jelas bukan yang paling liar.

Jumlah lingkungan untuk menentukan dependensi tetap benar-benar tidak dapat dikelola secara manual.

Cukup memasukkan Pipfile.lock ke dalam repositori agak mudah, tetapi tidak ada peningkatan ajaib (jika ya, tunjukkan skenario nyata, kapan itu akan memperbaiki situasi).

Mungkin Anda tahu aturan emas dari dunia "terkompilasi" dan merasa bahwa determinisme (atau pengulangan) adalah suatu keharusan untuk Python juga. Seperti yang Anda lihat, benar-benar banyak proyek Python hidup tanpanya dengan baik sehingga mungkin aturan emas tidak berlaku begitu ketat di sini.

Saya akan senang, jika kami menemukan penggunaan pipenv untuk pustaka python yang akan memperbaiki situasi. Dan saya ingin mencegah penggunaan, yang akan merusak kualitas secara keseluruhan.

Untuk mencapai tujuan itu, pendekatan saya adalah mengulangi pertanyaan:

  • Haruskah saya menggunakan alat itu?
  • Bagaimana?
  • Mengapa, nilai apa yang saya dapatkan?
  • Apakah itu menimbulkan beberapa masalah? (kerja ekstra, kesalahan disembunyikan ...)

@feluxe

Maaf jika ini tidak jelas. Ketergantungan lib saya dimaksudkan untuk menjadi apa yang saat ini dimasukkan orang ke setup.py / install_requires. Mungkin pypi-dependencies akan menjadi nama yang lebih baik untuk apa yang saya maksud.

Lihat diskusi pbr dalam edisi ini. Ini adalah upaya untuk mendukung dependensi perpustakaan oleh Pipfile.

Saya pikir, satu Pipfile tidak boleh digunakan untuk dua tujuan (lib dan aplikasi), hal-hal ini harus dilakukan secara terpisah. Jika Anda merasa itu benar-benar dibutuhkan, dapatkah Anda menjelaskan tujuan proyek menggunakannya? Saya biasanya mencoba untuk memisahkan proyek pengembangan dan penyebaran perpustakaan karena mereka memiliki penggunaan waktu yang sangat berbeda.

@vlcinsky Saya tidak begitu yakin ke mana Anda ingin membawa ini (saya tidak yakin PR seperti apa yang Anda minta!), Jadi saya akan keluar dari percakapan ini untuk saat ini.

Untuk menyatakan kembali TL;DR dari posisi saya:

  1. Build deterministik sangat diinginkan, umum di tempat lain dalam industri perangkat lunak, dan mudah dicapai dengan Pipenv.
  2. Pasti ada beberapa kasus tepi, dan seseorang harus mendorong maju ke depan di sana (melalui solusi atau melalui perkakas yang lebih baik).
  3. Tidak bertanggung jawab jika dokumen Pipenv menolak rekomendasi (1) hanya karena (2) memengaruhi sebagian kecil kasus.

@uranusjr Mengerti. Meskipun saya tidak berpikir ada bahasa khusus di sini, hanya saja komunitas yang berbeda telah menetapkan heuristik yang berbeda untuk menangani masalah tanpa solusi umum - jika Anda memiliki konflik versi, Anda memiliki masalah.

Maven/Java (misalnya) memaksa Anda untuk memikirkannya saat membangun. Cara NPM berarti Anda memiliki masalah runtime jika versi yang tidak cocok melintasi antarmuka. Resolusi runtime (mis. Python, pustaka dinamis) berarti ketergantungan mungkin macet/dll. jika versi ketergantungan tidak seperti yang diharapkan.

@vlcinsky

Lihat diskusi pbr dalam edisi ini. Ini adalah upaya untuk mendukung dependensi perpustakaan oleh Pipfile.

pbr tampaknya bagus dan semuanya, tetapi itu termasuk dalam kategori yang saya coba atasi dengan ini:

Saya pikir sesuatu seperti ini akan menghilangkan kebutuhan akan bagian anti-pola dan alat pihak ketiga untuk mengisi celah.

Saya pikir alat seperti itu seharusnya tidak diperlukan sejak awal.

Jika Anda merasa itu benar-benar dibutuhkan, dapatkah Anda menjelaskan tujuan proyek menggunakannya? Saya biasanya mencoba untuk memisahkan proyek pengembangan dan penyebaran perpustakaan karena mereka memiliki penggunaan waktu yang sangat berbeda.

Ketika datang ke paket pypi, saya akhirnya menggunakan Pipenv untuk menangani dependensi dev, Pipfile untuk menggambarkan dependensi dev, setup.py untuk menggambarkan dependensi lib dengan install_requires dan setuptools di setup.py untuk mempublikasikan paket saya yang berjalan pipenv run python setup.py bdist_wheel upload . Ini yang saya anggap rumit.

Dalam bahasa modern lainnya saya harus mempelajari satu alat baris perintah (manajer paket) ditambah satu format file ketergantungan. Dokumentasi ada di satu tempat dan lebih mudah diikuti dan pendatang baru akan menyelesaikan semua ini dalam beberapa jam. Ini soal npm init , npm install foo --dev , npm publish . Pipenv/Pipfile sudah bisa melakukan sebagian besar, jika bisa melakukan semuanya, masalah seperti ini tidak akan ada.

Saya mengulangi panggilan saya untuk semacam bagian/wiki "komunitas" untuk diskusi ini. Ada beberapa "pola" yang sah dan beberapa dari kita mungkin ingin membagikannya "cara melakukan perpustakaan python", beberapa seperti saya dengan pbr, dan yang lain mungkin memiliki pola yang sangat bagus. Tetapi halaman di dalam dokumen pipenv, tidak yakin apakah itu ide yang bagus.

PS: untuk mempersiapkan migrasi ke pypi baru, Anda harus menggunakan benang dan bukan python setup.py upload. Menggunakan "upload" harus dianggap sebagai antipattern.

Mungkin pipenv dapat menumbuhkan perintah "terbitkan"?

@feluxe Anda mungkin ingin melihat puisi . Saya baru saja menemukannya dan sepertinya itulah yang Anda cari.

Itu melakukan apa yang dilakukan pipenv dan lebih banyak lagi dan tampaknya mereka melakukannya dengan lebih baik terutama mengenai manajemen ketergantungan (setidaknya itulah yang mereka pura-pura). Itu melakukan manajemen ketergantungan, pengemasan, dan penerbitan semua alat tunggal poetry .

Saya ingin tahu apakah pipenv dan poetry dapat mengumpulkan upaya untuk akhirnya memberi Python manajer paket yang sebenarnya.

Saya ingin mengulangi diri saya lagi sebelum diskusi ini terlalu jauh. Pipenv tidak bisa begitu saja menumbuhkan perintah publish , atau melakukan apa pun yang mencoba mengambil alih tugas pengemasan. Ini hanya akan memecah ekosistem lebih banyak karena tidak semua orang melakukannya dengan cara ini, dan dengan dependensi aplikasi dan lib secara teoritis berbeda, Anda tidak dapat memberi tahu seseorang untuk menggabungkannya kembali setelah perbedaan dibuat dalam alur kerja mereka.

Tampaknya hampir semua orang bergabung dengan penggabungan ini , tetapi sebenarnya ada lebih banyak orang yang tidak bergabung dalam diskusi ini karena hal-hal berhasil untuk mereka dan mereka melakukan sesuatu yang lain. Saya telah berulang kali mengatakannya: Diskusi tentang peningkatan desain rantai alat dan format file harus terjadi di suatu tempat yang lebih tinggi dalam hierarki pengemasan Python, sehingga ia menerima lebih banyak paparan kepada orang-orang yang merancang hal-hal yang lebih mendasar yang diandalkan oleh Pipenv. Silakan diskusi di sana. Tidak ada gunanya menyarankannya di sini, karena Pipenv tidak dalam posisi untuk mengubahnya.

Saya telah berulang kali mengatakannya: Diskusi tentang peningkatan desain rantai alat dan format file harus terjadi di suatu tempat yang lebih tinggi dalam hierarki pengemasan Python, sehingga ia menerima lebih banyak paparan kepada orang-orang yang merancang hal-hal yang lebih mendasar yang diandalkan oleh Pipenv.

Saya setuju bahwa diskusi tentang bug ini menjadi tidak terkendali sekarang setelah pengemasan dan penerbitan muncul (bug ini hanya tentang manajemen ketergantungan!), tetapi bisakah Anda mengarahkan kami ke tempat yang tepat untuk melakukan diskusi ini? Orang-orang melakukannya di sini karena pipenv dipandang sebagai langkah yang sangat dibutuhkan ke arah yang benar, bukan karena mereka ingin membebankan tanggung jawab tambahan kepada pengelola pipenv.

Sunting : Maaf, saya pasti melewatkan posting di mana Anda melakukan hal itu ketika membaca komentar baru pertama kali.

Namun, dalam ruang lingkup proposal ini, saya menyarankannya untuk fokus pada praktik terbaik yang mungkin saat ini, alih-alih masuk ke lubang kelinci untuk mengerjakan alur kerja baru untuk seluruh komunitas pengemasan Python. Akan lebih produktif untuk mengusulkan praktik terbaik dalam batasan saat ini, dan kemudian memulai diskusi untuk perbaikan.

Saya sangat setuju dengan ini. Pertama-tama kita harus mencari tahu apa alur kerja terbaik untuk pengelola perpustakaan sekarang sebelum kita membuat rencana besar. Jadi mari kita fokus pada hal itu lagi, seperti yang kita lakukan di awal utas ini. Saya rasa kita belum mencapai kesimpulan.

Kembali ke topik: Mengutip posting @uranusjr tentang mengapa dependensi harus didefinisikan dalam file yang berbeda untuk perpustakaan:

Cara lain untuk mengatasi ini adalah dengan melakukan sesuatu yang cerdas dalam alat pengemasan yang "melepaskan" versi ketergantungan. Bundler (dari Ruby) melakukan ini, dengan merekomendasikan orang untuk tidak memasukkan file kunci ke dalam permata, sehingga Bundler dapat menggunakan versi yang tidak disematkan di Gemfile, alih-alih versi yang disematkan di Gemfile.lock. Tetapi orang cenderung mengabaikan saran dan melakukan apa pun yang mereka inginkan, jadi Anda masih mendapatkan versi yang disematkan di mana-mana.

Saya mungkin agak terlalu kuat untuk mengatakan bahwa itu tidak akan berhasil. Tapi setidaknya semua percobaan sebelumnya gagal

Saya masih tidak mengerti mengapa rekomendasi resmi untuk perpustakaan untuk saat ini tidak dapat menggunakan pipenv untuk build CI mereka, tetapi jauhkan Pipfile.lock dari kontrol sumber. Karena, seperti yang ditunjukkan beberapa orang, pipenv saat ini tidak ada hubungannya dengan proses pengemasan, kami seharusnya tidak mengalami masalah yang Anda uraikan di atas.

Dan saya juga tidak mengerti mengapa ini merupakan argumen yang menentang pendefinisian dependensi abstrak Anda dalam file yang sama yang digunakan aplikasi untuk mendefinisikan dependensi abstraknya. Tidak apa-apa jika pipenv tidak ingin menerapkan solusi rumit untuk mengintegrasikan Pipfile dengan setup.py , tetapi saya tidak mengerti mengapa itu ide yang buruk secara umum.

@vlcinsky

Saya pikir, satu Pipfile tidak boleh digunakan untuk dua tujuan (lib dan aplikasi), hal-hal ini harus dilakukan secara terpisah.

Lihat postingan saya di atas. Bisakah Anda menjelaskan mengapa Anda berpikir demikian? Saya tidak bisa melihat kerugian pada prinsipnya. Saat ini, mungkin ide yang buruk untuk menyertakan Pipfile , karena Anda kemudian harus mendefinisikan dependensi dengan cara yang sama di dua file yang berbeda, tetapi saya belum melihat argumen yang menjelaskan alasannya itu akan menjadi ide yang buruk untuk menggunakan Pipfile untuk deklarasi ketergantungan secara umum.

Perhatikan bahwa saya sudah setuju bahwa Pipfile.lock tidak boleh berada dalam kontrol sumber untuk perpustakaan kecuali Anda berada dalam situasi yang sama dengan saya.

Sunting : Juga, jika ternyata pipenv itu sendiri sebenarnya perlu tahu tentang perbedaannya, Anda mungkin hanya memperkenalkan sesuatu seperti bidang crate-type kargo sebelum Anda mulai memperkenalkan app-dependencies dan lib-dependencies - kedengarannya terlalu rumit.

@Moritz90 Beberapa milis Python akan menjadi tempat yang baik untuk mengadakan diskusi ini.

pypa-dev adalah yang paling pasti untuk diskusi yang berpusat pada kemasan Python, dan ekosistem di sekitarnya. Saya mungkin akan mulai di sini jika saya memposting diskusi serupa.

python-ideas adalah tempat untuk mendiskusikan ide, dan memiliki visibilitas yang cukup tinggi ke seluruh komunitas Python. Ini juga akan menjadi titik awal yang baik jika Anda ingin mendorong ini ke tingkat PEP (pada akhirnya Anda akan melakukannya, saya pikir).

@tsiq-oliverc

Maksud saya PR: tunjukkan contoh yang membuktikan konsep Anda layak.

Jadi ambil beberapa perpustakaan yang ada, garpu itu, terapkan (1) Anda - Anda mengatakan itu akan mudah dengan pipenv dan tunjukkan kepada saya. Saya mencoba cukup keras dan mengalami kesulitan.

Jika (2) Anda berarti "orang lain harus melakukan pekerjaan", PR Anda tidak akan ada.

Dalam (3) Anda berbicara tentang "subset kecil dari kasus" tanpa memberikan bilangan real. Apakah semua perpustakaan teratas yang saya jelaskan sehubungan dengan jumlah virtualenvs dianggap "subset kecil"?

Untuk mengakhiri diskusi ini, saya membuat ringkasan singkat dari apa yang ditemukan selama diskusi.

Fokus: pipenv (anti)pola untuk pustaka dan aplikasi python

Saya mengubah fokus sedikit: ini berbicara tidak hanya tentang perpustakaan python (umum), tetapi juga tentang aplikasi karena agak murah untuk memasukkannya dan itu menunjukkan perbedaan dengan baik.

Saya sengaja mengecualikan apa pun yang mengusulkan perubahan pada alat yang ada seperti pipenv , tox dll.

Apa itu pipenv dan apa yang bukan

  • itu adalah alat penyebaran, memungkinkan untuk mendefinisikan dan menerapkan dependensi konkret melalui Pipfile.lock .
  • itu adalah alat manajemen virtualenv.
  • itu BUKAN alat pengemasan dalam arti menghasilkan paket python.

Perpustakaan dan aplikasi

Produk (perangkat lunak python) siap digunakan di produk lain (dengan demikian perpustakaan) atau merupakan aplikasi akhir yang siap dijalankan.

Secara pribadi saya pikir, bahkan "perpustakaan perusahaan" termasuk dalam kategori perpustakaan (aturan yang sama berlaku, hanya jumlah konteks eksekusi yang lebih kecil).

Jenis produk perangkat lunak

  • perpustakaan: untuk digunakan di produk lain (perpustakaan atau aplikasi)
  • aplikasi: untuk digunakan dan dijalankan

Metode instalasi:

  • library: pipenv install <package> sehingga "dapatkan paket ke dalam permainan (menyelesaikan versi untuk perpustakaan lain di sekitar)"
  • aplikasi: pipenv sync jadi "terapkan dependensi konkret"

Ketergantungan abstrak dan konkret

ketergantungan produk perangkat lunak

  • dependensi abstrak: harus menyebutkan pustaka yang digunakan, dapat membatasi versi atau penggunaan, tetapi harus tetap cukup fleksibel (tidak boleh menyematkan versi)
  • dependensi konkret: harus menyematkan versi, idealnya dengan hash perpustakaan bekas

    pipenv artefak:

  • Pipfile : dependensi abstrak

  • Pipfile.lock : dependensi beton (terkunci)"

Konteks eksekusi

Jumlah khas dari konteks eksekusi yang berbeda

  • Perpustakaan:

    • python virtualenvs pada satu OS: 3 hingga 9 (tornado menggunakan 30)

    • jumlah OS: 1 hingga 3 (Linux, OSX, Windows)

    • jumlah total: 3 hingga 18

  • aplikasi:

    • python virtualenvs pada satu OS: 1

    • jumlah OS: 1

    • jumlah total: 1 (atau sangat sedikit)

Tujuan, prioritas, dan determinisme CI

tujuan CI

  • Perpustakaan:

    • kode termasuk dependensi abstraknya memungkinkan instalasi dan fungsi yang diharapkan dalam semua varian konteks eksekusi yang diharapkan.

    • ketika (swasta/publik) pypi mendapatkan pembaruan perpustakaan ketergantungan, gagal, jika itu memengaruhi instalasi fungsi perpustakaan yang diuji.

  • aplikasi:

    • saat diinstal (menggunakan dependensi beton/sematkan), semua fungsionalitas yang diharapkan disediakan dalam satu konteks eksekusi yang telah ditentukan sebelumnya

Sasaran CI khusus terkait fungsionalitas:

  • Perpustakaan:

    • dependensi abstrak yang dideklarasikan oleh perpustakaan selesai dan mencakup semua batasan yang diperlukan (hanya jika diperlukan): perpustakaan menginstal sendiri dengan benar

    • semua kasus penggunaan yang diharapkan berfungsi dengan baik

  • aplikasi:

    • ketergantungan beton selesai dan semua disematkan, termasuk yang terbaik. hash: aplikasi terpasang dengan benar

    • semua kasus penggunaan yang diharapkan berfungsi dengan baik

Mode uji CI yang berbeda

  • Mode: "Lari, Forrest, Lari"

    • Sebagian besar perpustakaan python saat ini diuji dengan cara ini.

    • gunakan tox atau pengujian serupa SW

    • Tidak ada penggunaan pipenv dan dependensi konkret (bisa baik untuk perpustakaan)

  • Mode: "Hasilkan dan segel"

    • Tidak ada Pipfile dalam repositori

    • Pipfile.lock dibuat oleh pipenv install -e .

    • Pipfile.lock mendokumentasikan (menyegel) lingkungan dan memungkinkan reproduksi virtualenv selanjutnya untuk menganalisis masalah.

  • Modus: "Zaman Es"

    • uji dua fase

      • ketika dependensi abstrak (didefinisikan dalam setup.py install_requires ) mengubah atau paket dependen pada pypi diperbarui, buat ulang Pipfile.lock oleh pipenv install -e .

    • uji coba fungsi: jalankan ketika kode perpustakaan berubah. Dijalankan dalam virtualenv yang dibuat oleh pipenv sync Pipfile.lock

      Bagaimana dan oleh siapa Pipfile.lock dibuat

  • secara manual oleh pengembang (mungkin berfungsi untuk aplikasi)

  • secara otomatis oleh CI build (dan lulus semua tes, nyatakan artefak yang diverifikasi)

Prioritas determinisme versus fleksibilitas

  • perpustakaan: fleksibilitas (jalankan bila memungkinkan)
  • aplikasi: determinisme (berjalan dengan cara yang persis sama dalam konteks eksekusi yang dipilih)

    Apa yang dapat memengaruhi determinisme produk yang dipasang:

  • pypi publik (determinisme rendah, paket diperbarui setiap saat)

  • pypi pribadi (determinisme lebih tinggi, pembaruan paket dapat dikontrol)
  • persyaratan abstrak dalam perpustakaan (tidak boleh digunakan untuk determinisme)
  • persyaratan konkret ( Pipfile.lock ): determinisme total

Aneka ragam

Beberapa kasus penggunaan untuk Pipfile.lock :

  • (antipattern) mendefinisikan dependensi abstrak perpustakaan (karena harus abstrak)
  • (antipattern) mengatur virtualenv untuk perpustakaan yang diuji (dapat menyembunyikan dependensi abstrak perpustakaan yang rusak)
  • mendokumentasikan virtualenv yang tepat ("segel"), tempat pengujian dijalankan (sehingga memungkinkan pengembang untuk membuatnya kembali nanti untuk pengujian yang rusak dan bereksperimen di dalamnya)
  • atur virtualenv untuk aplikasi yang diuji
  • menyebarkan aplikasi ke dalam produksi

    Petunjuk lainnya

  • pbr library memungkinkan definisi dependensi perpustakaan abstrak melalui requirements.txt . Pembaruan membaca Pipfile sedang dalam perjalanan.

  • poetry mencoba sesuatu yang mirip dengan pyenv

    Masalah umum

  • "jatuhkan lockfile ke repo" dan Anda mendapatkan build deterministik:

    • Akan bekerja untuk aplikasi.
    • Tidak akan berfungsi untuk perpustakaan, karena ada banyak konteks eksekusi dan masing-masing memiliki potensi bagus untuk menghasilkan Pipfile.lock . Serius: flask ditampilkan pada 11 env virtual yang berbeda (pada satu OS) 10 dependensi terkunci yang berbeda. Siapa yang akan membuat dan mengkomitnya?
    • Perhatikan, bahwa dengan mode CI "Hasilkan dan segel", Anda masih bisa mendapatkan Pipfile.lock (tetapi dihasilkan oleh skrip CI) yang memungkinkan untuk membuat ulang virtualenv di tempat lain.
  • Pipfile.lock di repositori perpustakaan

    • jika digunakan untuk membuat virtualenv, ia dapat menyembunyikan definisi dependensi perpustakaan yang rusak dalam setup.py .

  • Pipfile di repositori perpustakaan

    • jika mengulangi dependensi abstrak (yang harus didefinisikan dalam setup.py ), itu mungkin menyembunyikan deklarasi dependensi setup.py rusak.

    • direkomendasikan: Hasilkan Pipfile oleh pipenv install -e . atau pipenv install -e .[tests] jika Anda juga perlu menguji dependensi dan mereka dideklarasikan sebagai ekstra "tes" di setup.py

  • menambahkan pipenv install <something> ke dalam skrip CI

    • itu tidak banyak meningkatkan determinisme itu sendiri

    • lihat mode CI "Hasilkan dan segel" (maka semua instalasi ke virtualenv harus melalui pipenv ).

Kesimpulan

Pustaka Python (terutama yang umum) menunjukkan jumlah konteks eksekusi yang sangat tinggi. Pasalnya, dengan perpustakaan tujuannya terbukti fleksibilitas dalam kondisi yang berbeda. Fleksibilitas tampaknya lebih penting daripada build deterministik. Bagi orang-orang yang berasal dari dunia "kompilasi" ini mungkin terasa seperti antipattern yang sangat buruk. Faktanya adalah, sebagian besar (mungkin semua) pustaka python tidak menyediakan build deterministik (jika Anda mengetahui beberapa, beri tahu saya) dan Python masih berfungsi dengan sangat baik. Alasan aplikasi Python stile hidup mungkin: python sebagai bahasa scripting berbeda dari dunia yang dikompilasi. Alasan lainnya adalah, bahwa determinisme dapat (harus) diselesaikan selangkah kemudian segera setelah dan aplikasi (dibangun dari kumpulan perpustakaan) akan menyelesaikan persyaratan (alami dan dibenarkan) untuk determinisme.

Untuk aplikasi situasinya justru sebaliknya dan di sini determinisme sangat mudah dijangkau dengan alat seperti pipenv .

Apa yang harus dilakukan selanjutnya?

  • Saya tidak akan punya waktu untuk menangani ini selama satu atau dua minggu ke depan.
  • Saya bisa membayangkan membuat serangkaian entri blog di suatu tempat (tidak yakin di mana). Jika Anda tahu tempatnya (idealnya memungkinkan beberapa diskusi), itu akan menjadi tempat yang wajar untuk membiarkan konten direferensikan, didiskusikan dan akhirnya mungkin (jika bertahan) diletakkan di suatu tempat di batu :-).
  • Saya mengusulkan @uranusjr untuk mengambil alih kendali atas masalah ini (tutup, putuskan apa yang harus dilakukan selanjutnya, arahkan orang ke tempat lain atau apa pun yang tampaknya praktis)

Terima kasih semuanya untuk diskusi yang sangat menginspirasi - saya merasa sebagai pesan "Saya benar-benar tersesat dalam topik ini" refactored tiga kali - apa artinya secara alami kami menjadi lebih baik.

@vlcinsky poetry tidak ada hubungannya dengan pyenv . Ini sangat mirip pipenv (tetapi dengan implementasi yang jauh lebih baik mengenai pengelolaan perpustakaan dan aplikasi, IMO) tetapi dengan bagian pengemasan dan penerbitan.

Anda memiliki file pyproject.toml yang mendefinisikan proyek Anda dan dependensinya (dependensi abstrak) dan pyproject.lock yang menjelaskan dependensi yang disematkan dan disematkan untuk semua versi python dan platform pyproject.toml file telah ditentukan agar hanya memiliki satu file kunci deterministik untuk menghindari masalah yang dihadapi pipenv . Hanya saat menginstal, poetry akan memeriksa paket mana yang akan diinstal dengan memeriksanya terhadap lingkungan.

Dan ketika paket perpustakaan Anda, itu akan menggunakan dependensi abstrak (dan bukan yang disematkan) sehingga Anda menjaga fleksibilitas saat mendistribusikan paket Anda (melalui PyPI misalnya).

Keuntungan dari ini adalah ia akan menggunakan dependensi abstrak untuk perpustakaan dan file kunci untuk aplikasi. Ini adalah yang terbaik dari kedua dunia.

@zface puisi tidak menggunakan dependensi yang disematkan benar-benar mengalahkan seluruh tujuan. Pipenv adalah _idempoten_ dan ini membutuhkan _reproduksi_ lingkungan. Tolong berhenti menggunakan masalah ini sebagai platform untuk mencoba dan menjual kepada semua orang sesuatu yang telah terdaftar sebagai alasan pertama mengapa menggunakannya melalui pipenv yang penulis tidak suka cli. Pada akhirnya, perangkat lunak kami digunakan di ratusan ribu mesin dan benar-benar mengakui dan menggunakan praktik terbaik seputar pengemasan. Jika Anda tidak menginginkan lingkungan idempoten dan Anda ingin mengaburkan batas antara pengembangan dan pengemasan, mohon jangan berpartisipasi dalam diskusi ini karena kami tidak bergerak ke arah itu dan tidak akan produktif.

Pada dasarnya kami menghabiskan banyak waktu dan upaya untuk ketahanan sehingga proyek-proyek kecil yang membuat klaim tinggi tidak perlu menghabiskan banyak upaya karena orang-orang tidak menangani kasus-kasus tepi. Jika Anda benar-benar percaya bahwa alat lain menawarkan yang terbaik dari semua dunia, maka saya mendorong Anda untuk menggunakannya— pipenv sendiri tidak akan menangani pengemasan untuk Anda dalam waktu dekat, jika pernah.

@techalchemy Saya tidak menjual apa pun, sungguh, saya hanya mengarahkan pada ide-ide yang dapat digunakan dalam pipenv .

Dan poetry menyematkan dependensi di pyproject.lock , seperti yang dilakukan pipenv di Pipfile.lock . Jadi Anda memiliki reproduksi seperti yang disediakan pipenv . Jika Anda memiliki file kunci, itu akan digunakan dan menginstal ketergantungan yang disematkan dan jika saya tidak salah, itu juga yang dilakukan pipenv .

Satu-satunya waktu ia menggunakan dependensi abstrak adalah ketika ia mengemas proyek untuk distribusi (jadi pada dasarnya untuk perpustakaan) karena dalam hal ini Anda tidak ingin dependensi yang disematkan.

@vlcinsky Masih ada beberapa poin yang perlu

Mengenai puisi, saya pribadi bukan penggemar secara keseluruhan, tetapi memang banyak hal yang benar. Itu mungkin tidak boleh disebutkan dalam dokumen Pipenv karena melanggar beberapa praktik terbaik yang ingin didorong oleh pengembang Pipenv, tetapi harus disebutkan jika diskusi diadakan di pypa-dev atau serupa, untuk memberikan gambaran lengkap tentang bagaimana pengemasan ekosistem saat ini.

puisi juga dapat menggunakan lebih banyak perhatian dan kontribusi. Ini akan menjadi yang terbaik untuk komunitas, termasuk Pipenv. Dengan pilihan yang layak, orang dapat mempertimbangkan pilihan mereka alih-alih pergi ke Pipenv terlebih dahulu dan mengeluh karena tidak melakukan apa yang mereka harapkan. Persaingan yang baik antar perpustakaan juga dapat memacu perbaikan teknis di depan resolusi ketergantungan, yang dilakukan oleh Pipenv dan puisi (dan tidak keduanya secara sempurna). Kita bisa belajar banyak dari satu sama lain.

@uranusjr Ya, saya pikir beberapa hal diklarifikasi dan layak dibagikan dengan khalayak yang lebih luas. Bantuan Anda sangat diharapkan.

Bagaimana dengan "perancangan dokumentasi pasangan"? Saya pikir pada saat ini akan paling efektif untuk mengerjakannya dalam skala kecil dua orang saja.

Yang perlu dilakukan adalah (mungkin dengan satu atau dua iterasi):

  • di mana tepatnya kami dapat mempublikasikan itu
  • mengidentifikasi item dokumentasi (artikel, bagian)
  • memperjelas ruang lingkup dan tujuan setiap item
  • setuju pada garis besar
  • mengidentifikasi masalah terbuka
  • kerjakan mereka
  • tulis dok
  • terbitkan (dan berharap itu akan diterima)

Jika Anda merasa ingin menulisnya sendiri (berdasarkan apa yang telah dibahas) dan menjadikan saya sebagai reviewer, saya tidak akan mengeluh.

Saya akan menghubungi Anda melalui email untuk menyetujui tindakan selanjutnya.

@vlcinsky Saya juga tersedia sebagai @uranusjr di PySlackers (Ruang kerja Slack) jika Anda lebih suka interaksi waktu nyata. Pipenv memiliki saluran di sana ( #pipenv ).

@uranusjr Itulah yang saya maksud dengan mengumpulkan usaha. Python sangat membutuhkan pengelola paket yang baik seperti kargo. Ekosistem Python tidak ada artinya dibandingkan dengan bahasa lain karena kurangnya cara standar untuk melakukan sesuatu. Dan pipenv tidak akan membantu dengan itu, saya pikir.

Yang mengganggu saya adalah pipenv mengiklankan dirinya sebagai the officially recommended Python packaging tool padahal itu bukan alat pengemasan, jauh dari itu, yang menyesatkan pengguna. Ini hanyalah manajer ketergantungan yang digabungkan dengan manajer virtualenv.

Juga, Anda mengatakan bahwa itu terinspirasi oleh kargo, npm, benang yang merupakan alat pengemasan bersama dengan manajer ketergantungan sementara pemipaan tidak.

Dan inilah kelemahan pipenv , itu hanya memperkeruh air karena orang masih akan membuat kesalahan yang sama seperti sebelumnya dengan requirements.txt vs setup.py . Proyek masih akan dikemas dengan buruk dengan dependensi yang ditentukan dengan buruk di setup.py karena itu. Itulah yang dilakukan proyek seperti kargo dengan benar: mereka menangani semua aspek pengembangan proyek/aplikasi untuk memastikan konsistensi sementara proyek seperti pipenv tidak.

Dan ketika Anda mengatakan:

yang dilakukan oleh Pipenv dan puisi (dan keduanya tidak sempurna)

Apa maksudmu? Dari apa yang saya lihat, manajer ketergantungan mereka jauh lebih tangguh daripada yang disediakan oleh pipenv . Satu-satunya downside adalah bahwa mereka menggunakan PyPI JSON API yang terkadang tidak memiliki informasi ketergantungan karena paket yang diterbitkan dengan buruk.

Bagaimanapun, saya pikir, seperti yang Anda katakan, kedua proyek dapat saling belajar.

Dan, satu hal lagi, bagaimana masa depan pipenv jika, pada akhirnya, pip menangani Pipfile ? Apakah itu hanya akan menjadi manajer virtualenv?

Jika manajer ketergantungan puisi bergantung pada json api, itu tidak hanya terkadang salah karena 'paket yang diterbitkan dengan buruk', itu akan sangat terbatas dalam apa yang sebenarnya dapat diselesaikan dengan benar. Warehouse json api memposting dependensi _most recent_ bahkan jika Anda berurusan dengan versi lama, dan itu jika memiliki info itu sama sekali. Kami juga menggunakan json api, itu bagus karena cepat, tetapi tim infrastruktur memberi tahu kami untuk tidak mempercayainya. Tampaknya agak tidak jujur ​​​​untuk menyebut sesuatu yang tangguh jika itu bergantung pada sumber yang tidak dapat diandalkan untuk memulai.

Pada akhirnya tantangannya adalah membangun grafik ketergantungan yang mengeksekusi file setup karena saat ini, itulah cara kerja pengemasan. Tidak ada jalan lain. Grafik ketergantungan yang diselesaikan pada mesin saya mungkin berbeda dari grafik ketergantungan yang diselesaikan pada mesin Anda bahkan untuk paket yang sama.

Sangat mudah untuk melambaikan tangan dan berkata 'bukankah itu hanya menjadikan pipenv sebagai manajer virtualenv jika pip dapat membaca pipfile?' Tidak. Pipenv adalah manajer ketergantungan. Ini mengelola lingkungan idempoten dan menghasilkan file kunci yang dapat direproduksi. Saya menyadari ini pasti tampak sepele bagi Anda karena Anda mengabaikannya dan mengurangi alat ini menjadi manajer virtualenv, tetapi sebenarnya tidak. Kami menyelesaikan file kunci dan menyertakan penanda untuk versi python yang tidak Anda miliki, tidak gunakan, dan tetap tersedia sehingga Anda dapat menerapkan dan mereproduksi dengan tepat di seluruh platform dan versi python. Kami menggunakan beberapa metode resolusi termasuk menangani roda dan file lokal, repositori vcs (kami juga menyelesaikan grafik di sana) artefak jarak jauh, paket pypi, indeks pribadi, dll.

Pada akhirnya pip _will_ menangani pipfiles, itulah rencananya, sudah menjadi rencananya sejak format dibuat. Tapi itu sama dengan menanyakan 'tapi bagaimana kalau pip dapat menangani file persyaratan?' Pertanyaannya pada dasarnya identik. Pip dapat menginstal format itu. Itu tidak benar-benar relevan dengan fungsi apa pun yang saya jelaskan selain itu kami juga menginstal file (menggunakan pip, omong-omong).

@tekalkimia

Gudang json api memposting dependensi terbaru bahkan jika Anda berurusan dengan versi lama, dan itu jika memiliki info itu sama sekali

Ini benar-benar salah, Anda bisa mendapatkan dependensi versi tertentu dengan memanggil https://pypi.org/pypi/{project}/{release}/json . Jika Anda hanya menelepon https://pypi.org/pypi/{project}/json yakin Anda hanya akan mendapatkan dependensi terakhir tetapi Anda benar-benar bisa mendapatkan set dependensi yang tepat.

Dan bagian pengemasan/penerbitan proyek python sangat perlu ditingkatkan karena pada akhirnya akan menguntungkan semua orang, karena memungkinkan penggunaan JSON API dengan andal.

Ini mengelola lingkungan idempoten dan menghasilkan file kunci yang dapat direproduksi.
Kami menyelesaikan file kunci dan menyertakan penanda untuk versi python yang tidak Anda miliki, tidak gunakan, dan tetap tersedia sehingga Anda dapat menerapkan dan mereproduksi dengan tepat di seluruh platform dan versi python.

Dan begitu juga poetry . Dan Anda dapat membuatnya tidak menggunakan JSON API untuk menyediakan penggunaan metode resolusi yang sama seperti pipenv (menggunakan pip-tools). Lihat https://github.com/sdispater/poetry/issues/37#issuecomment -379071989 dan itu masih akan lebih tangguh daripada pipenv (https://github.com/sdispater/poetry#dependency-resolusi )

@zface Saya akan mengatakan ini untuk terakhir kalinya, tolong bawa ini ke tempat yang lebih tinggi dalam hierarki. Pipenv tidak memproklamirkan diri sebagai alat pengemasan Python yang direkomendasikan secara resmi; mengatakan bahwa karena itu . Jika Anda merasa itu tidak pantas, sampaikan kepada pejabat yang merekomendasikan Pipenv . Tolong jangan letakkan hal-hal ini di dev Pipenv. Ini adalah tempat yang salah untuk mengeluh, dan Anda tidak mungkin mendapatkan solusi untuk keluhan Anda di sini. Anda juga bisa mendapatkan jawaban yang lebih baik atas pertanyaan teknis yang Anda miliki di sana. Ini adalah pelacak masalah untuk Pipenv, bukan papan diskusi untuk alat pengemasan Python dan bagaimana pengemasan Python dilakukan.

Pipenv tidak hanya mengandalkan alat pip untuk resolusi, tolong hentikan pengurangan perangkat lunak kami menjadi satu baris yang menunjukkan kurangnya pemahaman. Saya tahu betul cara kerja api PyPI, saya berbicara langsung dengan tim yang mengimplementasikannya.

Ini benar-benar salah,

Sikap seperti ini tidak diterima di sini. Jangan berasumsi bahwa kita tidak mengerti apa yang kita bicarakan. Silakan berlatih sopan santun.

itu masih akan lebih tangguh daripada pipenv (https://github.com/sdispater/poetry#dependency-resolution)

Pipenv saat ini tidak meratakan grafik ketergantungan. Menunjuk ke satu masalah spesifik di mana pohon telah diratakan dan mengklaim seluruh alat karena itu lebih baik dan lebih tangguh adalah bodoh, Anda membuktikan berulang kali bahwa Anda hanya di sini untuk menghina pipenv dan mempromosikan puisi. Harap di jalan Anda, perilaku ini tidak diterima.

Saya setuju diskusinya jauh di luar topik, yang mencoba memanfaatkan "praktik baik" di sekitar pipenv.

Namun,

[...] masih akan membuat kesalahan yang sama seperti sebelumnya dengan requirements.txt vs setup.py. Proyek masih akan dikemas dengan buruk dengan dependensi yang ditentukan dengan buruk di setup.py mereka karena itu.

Saya berbagi pendapat ini, membuat pengembang baru berhasil mengemas kode Python mereka sendiri sebenarnya rumit, terlalu rumit, perlu membaca banyak dokumentasi online.
Tetapi tidak tergantung pada pipenv atau ketergantungan paket lainnya untuk menanganinya sepenuhnya. Kami tidak bisa menulis ulang sejarah. Kami, sebagai komunitas, perlu menemukan cara untuk memodernisasi rantai alat python, langkah demi langkah.

Dan pipenv (dan mungkin puisi) adalah langkah maju yang sangat baik.

Harus memelihara di satu sisi Pipfile untuk aplikasi dan setup.py untuk perpustakaan di sisi lain, tidak perlu dipikirkan. Tidak peduli seberapa keras kami menjelaskan dengan banyak kata dan artikel panjang dan panduan praktik yang baik, itu terlalu rumit untuk apa itu. Saya sepenuhnya setuju untuk saat ini seperti ini, tetapi seharusnya tidak menghalangi kita untuk membayangkan cara yang lebih baik dan lebih aman.
Pada akhirnya, sebagai pengembang, saya menginginkan satu alat, mungkin dengan dua mode berbeda, untuk membantu saya dan membuat hidup saya semudah mungkin.

Mereka harus menjadi cara mengekstrak hanya bagian yang melakukan requirements.txt/Pipfile dari lib seperti PBR untuk mengusulkan semacam 'pengaturan mudah.py', pembungkus Pipfile-aware di sekitar install_requires , tanpa semua perilaku yang tidak diinginkan pbr membawa, dan paket itu dalam pembungkus setuptools khusus yang hanya melakukan itu.

Jadi kita akan dapat memiliki yang lebih baik dari setiap dunia:

  • pipenv untuk mempertahankan Pipfile (versi di kedua perpustakaan dan aplikasi)
  • pipenv untuk mempertahankan Pipfile.lock (versi hanya untuk aplikasi)
  • seseorang akan menggunakan paket pembungkus ajaib ini ( pipfile_setuptools , install_requires_pipfile ?) yang akan menjadi ketergantungan tingkat pertama yang tugasnya hanya menyuntikkan Pipfile ke install_requires .

Ini proyek lain yang tidak akan terkait dengan pipenv , tetapi masih membutuhkan perpustakaan parser Pipfile generik. Bagaimana menurutmu?

@gsemet Dari pemahaman saya, PyPA telah mencoba mengisinya dengan pyproject.toml sebagai gantinya, dipimpin oleh flit . Anda harus berbicara dengan mereka terlebih dahulu (di pypa-dev atau distutils-sig) tentang hal ini sebelum melanjutkan menggunakan Pipfile sebagai format sumber. Adapun parsing Pipfile (dan file kunci), yang ditangani di pypa/pipfile (yang vendor Pipenv menyediakan logika parsing inti).


Sunting: Tolong kirimkan saya pesan jika Anda memutuskan untuk memulai diskusi tentang ini di salah satu milis. Saya memiliki beberapa ide bagaimana kita dapat menyatukan dua bagian dari distribusi pengemasan Python.

Saya harus mengakui bahwa saya agak sedih melihat dependensi dideklarasikan dalam pyproject.toml (yang mengambil peran sebagai setup.cfg dilakukan oleh PBR), sementara PyPa juga mendukung Pipfile ....

Terima kasih atas penunjuk ke flit dan pipfile. Ada juga pipenvlib Kennethreitz yang tampaknya lebih ringan.

setup.cfg PBR tampaknya lebih lengkap dibandingkan dengan dokumentasi resmi (mis: data_files ) dan menggunakan kembali file yang sudah dibagikan dengan beberapa alat (flake8, pytest, ...) dapat menggunakan file yang sama, mengurangi jumlah file di root proyek python)

Apakah halaman ini membantu?
0 / 5 - 0 peringkat