Pipenv: Sasaran: memastikan konsistensi file kunci setelah semua perintah instalasi

Dibuat pada 31 Des 2017  ·  50Komentar  ·  Sumber: pypa/pipenv

Seperti disebutkan dalam https://github.com/pypa/pipenv/issues/1137 , pipenv saat ini tidak memeriksa konflik persyaratan antara [packages] dan [dev-packages] , yang dapat menyebabkan masalah saat mencoba menghasilkan requirements.txt datar yang mencakup keduanya, serta menyebabkan keanehan umum saat dependensi berkonflik.

Cara kerja pipenv install (menjalankan instalasi dan kemudian memperbarui file kunci) berarti juga relatif mudah bagi lingkungan lokal untuk keluar dari sinkronisasi dengan file kunci: jika permintaan instalasi mencakup paket yang sudah diinstal, maka itu tidak akan diperbarui secara lokal, tetapi file kunci akan diperbarui ke versi terbaru yang tersedia dari indeks paket yang dikonfigurasi.

Masalah ini tidak mencakup permintaan fitur individual. Alih-alih, ini menetapkan tujuan untuk membantu memastikan konsistensi antara file kunci dan lingkungan lokal dengan menyusun perintah penginstalan untuk memodifikasi file kunci terlebih dahulu , dan kemudian menggunakan file kunci yang diperbarui untuk mendorong langkah penginstalan yang sebenarnya. (Kami tidak memiliki target ETA apa pun untuk berapa lama pekerjaan ini akan berlangsung - menuliskannya hanya dimaksudkan untuk membantu memastikan kita semua menuju ke arah yang sama, dan semua nyaman dengan arah itu)

Aspek kunci dari ini adalah memperjelas pembagian tanggung jawab antara pipenv install , pipenv uninstall , pipenv lock , dan pipenv update (dan berpotensi menambahkan satu atau lebih perintah baru jika dianggap perlu).

Sub-langkah yang diusulkan:

  • [x] tambahkan subperintah pipenv sync yang memastikan bahwa lingkungan saat ini cocok dengan file kunci (mirip dengan pip-sync dalam pip-tools ). (Diimplementasikan oleh @kennethreitz untuk 10.0.0, dengan pipenv sync memastikan versi paket terkunci cocok dengan file kunci, sementara pipenv clean menghapus paket yang tidak ada di file kunci. Saya suka perubahan itu relatif ke pip-sync , karena itu berarti menyertakan sinkronisasi implisit dalam perintah lain tidak akan secara tiba-tiba menghapus apa pun dari lingkungan virtual)
  • [x] Pertahankan perilaku saat ini untuk pipenv install tanpa argumen, tetapi alihkan ke merekomendasikan penggunaan pipenv sync saat menyiapkan lingkungan baru (dengan cara itu pipenv install digunakan terutama untuk mengganti komponen yang terpasang)
  • [x] perbarui pipenv lock untuk selalu memastikan bahwa [packages] dan [dev-packages] konsisten satu sama lain (resolusi untuk #1137)
  • [x] ubah pipenv update menjadi setara dengan pipenv lock && pipenv sync (pembaruan pipenv malah dihapus seluruhnya - perilaku lama sebenarnya sebanding dengan apa yang sekarang pipenv sync && pipenv clean )
  • [x] tambahkan opsi pipenv lock --keep-outdated yang masih menghasilkan Pipfile.lock dari Pipfile , tetapi meminimalkan perubahan yang dibuat hanya yang diperlukan untuk memenuhi setiap perubahan yang dibuat pada Pipfile (apakah itu penambahan paket, penghapusan, atau perubahan batasan versi)
  • [x] ubah pipenv install <packages> menjadi setara dengan "tambah atau perbarui entri di Pipfile" diikuti oleh pipenv lock && pipenv sync (diimplementasikan di #1486).
  • [x] Tambahkan opsi --keep-outdated ke pemasangan pipenv yang diteruskan ke operasi pipenv lock .
  • [x] tambahkan fitur pipenv install --selective-upgrade <packages> yang secara semantik setara dengan "hapus entri paket tersebut dari Pipfile (jika ada)", jalankan pipenv lock --keep-outdated , lalu jalankan pipenv install --keep-outdated <packages> (ini adalah langkah terakhir yang memberikan dukungan untuk https://github.com/pypa/pipenv/issues/966). Jika hanya nama paket yang diberikan, maka batasan versi yang ada di Pipfile digunakan, jika tidak, batasan versi yang diberikan akan menimpa yang sudah ada. Efek ini pada lingkungan saat ini harus sama dengan pip install --upgrade --upgrade-strategy=only-if-needed <packages> di pip 9+ (kecuali Pipfile.lock juga akan diperbarui).

Jika ada yang ingin mengambil salah satu dari sub-langkah ini, beri komentar di bawah untuk mengatakan bahwa Anda sedang mengerjakannya (untuk mencoba meminimalkan duplikasi upaya), lalu ajukan PR yang menautkan kembali ke masalah ini. (Langkah-langkah yang tercantum sebelumnya perlu diselesaikan sebelum langkah-langkah selanjutnya praktis)

Pertanyaan-pertanyaan terbuka:

  • Tidak ada

Pertanyaan yang diselesaikan (setidaknya untuk waktu dekat):

  • pipenv lock akan terus memutakhirkan semuanya secara default, dengan pipenv lock --keep-outdated untuk meminta pembaruan minimal yang hanya menyesuaikan file kunci untuk memperhitungkan perubahan Pipfile (penambahan, penghapusan, dan perubahan batasan versi)
  • pipenv lock --skip-lock akan terus berfungsi seperti hari ini (walaupun itu berarti file kunci dan lingkungan lokal dapat tidak sinkron: gunakan pipenv sync && pipenv clean untuk menyinkronkannya kembali)
  • pipenv install dan pipenv install <package> akan terus menyiratkan pipenv lock secara default, dengan pipenv install --keep-outdated diperlukan untuk meminta hanya perubahan minimal yang diperlukan untuk memenuhi permintaan instalasi
  • pipenv install <package> akan terus mempertahankan batasan versi yang ada di Pipfile jika tidak ada yang diberikan pada baris perintah, bahkan untuk opsi --selective-upgrade
  • pipenv uninstall <package> hanya akan menghapus paket yang ditentukan, dan karenanya dapat meninggalkan ketergantungan yang tidak lagi diperlukan di lingkungan lokal. Menjalankan pipenv lock && pipenv sync && pipenv clean akan menghapusnya.

Catatan: proposal asli di sini hanya untuk memastikan bahwa [dev-packages] dan [packages] tetap sinkron saat membuat file kunci, dan beberapa posting pertama mencerminkan hal itu. Proposal saat ini malah mencakup proposal pembaruan simetris berbasis file kunci yang pertama kali disebutkan di https://github.com/pypa/pipenv/issues/1255#issuecomment -354585775

Future Discussion Type

Komentar yang paling membantu

--selective-upgrade selesai.

Semua 50 komentar

Memperhatikan tantangan implementasi potensial di sini: Saya tidak yakin bahwa pip-tools saat ini mendukung file kendala, dalam hal ini kita perlu menambahkan dukungan itu terlebih dahulu untuk mendapatkan manfaat penuh dari pendekatan ini.

Namun, deteksi konflik waktu pemasangan harus dimungkinkan, karena pip digunakan untuk menangani pemasangan yang sebenarnya.

Anda tidak perlu menunggu sampai waktu penginstalan per se. Anda dapat melakukan ini saat menyelesaikan dependensi transitif penuh untuk file kunci.

Anda sebagian besar dapat melakukan ini dengan LocalRequirementsRepository per saran @vphilippon untuk tidak memperbarui dependensi yang tidak terkait di https://github.com/pypa/pipenv/issues/966#issuecomment -339707418. Itu terlihat seperti https://github.com/taion/pipf/blob/1feee35a2e4480bc7e5b53bfab17587d37bdf9dd/pipf/pipfile.py#L175 -L185.

Lihat juga https://github.com/pypa/pipfile/issues/100. Masih merupakan masalah utama bahwa Pipfile.lock bahkan dapat mewakili beberapa set dependensi yang tidak kompatibel untuk grup yang berbeda.

@taion Kami tidak akan mengalihkan Pipfile.lock ke representasi datar, karena kami ingin mendukung alat yang mengunci kembali dependensi penerapan tanpa melihat dependensi pengembangan. Ya, itu berarti bagian [dev-packages] mungkin ketinggalan zaman, tetapi itulah tujuan dari masalah ini: memastikan bahwa ketika bagian [dev-packages] diperbarui, itu akan disinkronkan ulang dengan bagian paket penyebaran.

Jika kami dapat mendeteksi konflik apa pun pada waktu penguncian alih-alih pada waktu pemasangan, itu akan sangat baik.

Dalam praktiknya dari perspektif pengguna itu hanya kasus khusus https://github.com/pypa/pipenv/issues/966 dan masalah terkait (tertutup) lainnya.

Seperti kasus terburuk, Anda hanya men-cache dependensi transitif yang diselesaikan di file kunci. Yarn dan npm sudah melakukannya. Ini akan memungkinkan Anda memperbarui semua deps prod Anda tanpa menekan PyPI untuk deps dev.

Kecuali saya kehilangan sesuatu, tidak ada manfaat aktif dari membiarkan hal-hal menyimpang dari sinkronisasi. Sebagai seseorang yang menghabiskan banyak waktu dengan pola manajemen paket ini, sebagian besar penyimpangan dari cara kerja alat yang ada tampaknya hanya menimbulkan rasa sakit.

Saya juga akan menambahkan bahwa npm sebenarnya mendukung pembaruan hanya dependensi produksi dan bukan pengembangan, dan sebenarnya menggunakan file kunci datar (dengan resolusi cache).

Yang cukup menarik, Yarn tidak untuk sub-perintah "perbarui dependensi" massalnya (meskipun versi interaktifnya membagi prod dan dev deps), dan sepertinya tidak ada yang mengeluh tentang hal itu, tetapi itu mungkin dapat dihubungkan ke npm -sama menggunakan rentang tanda sisipan untuk dependensi secara default, ditambah orang-orang yang umumnya cukup baik tentang mengikuti SemVer jarang menyebabkan masalah pengguna dari menabrak deps dev. Ekosistem Python, tidak begitu banyak.

@taion pipenv lock eksplisit sudah sepenuhnya menyelesaikan [packages] dan [dev-packages] , jadi kita tidak perlu khawatir tentang penyimpangan konfigurasi dalam kasus itu (dan itulah kasus di mana saya pikir paling diinginkan untuk mendeteksi konflik ketergantungan).

Jika ada solusi simetris yang juga memungkinkan pipenv install package dan pipenv install --dev package untuk mendeteksi (dan menyelesaikan) inkonsistensi, maka saya setuju bahwa itu akan menjadi cara yang baik. Namun, saya juga setuju dengan solusi asimetris, jika itu lebih mudah diterapkan (karenanya membingkai proposal ini).

Untuk pendekatan simetris, saya pikir salah satu cara membingkai & mengimplementasikannya adalah dengan mengejar pendekatan yang dijelaskan oleh @vphilippon di https://github.com/pypa/pipenv/issues/966#issuecomment -339791934, tetapi susun sebagai berikut :

  • tambahkan opsi pipenv lock --keep-outdated untuk meminta pembaruan lockfile minimal daripada yang komprehensif default
  • ubah pipenv install package menjadi "edit Pipfile -> pipenv lock --keep-outdated -> pipenv install "

(Catatan: untuk alasan manajemen keamanan, saya benar - pipenv lock sebagai memutakhirkan semuanya - namun, menurut saya fitur seperti --keep-outdated memiliki tempat ketika mekanisme lain tersedia untuk memastikan tanggapan yang tepat waktu terhadap masalah keamanan yang dilaporkan dalam dependensi)

Perilaku yang Anda gambarkan untuk pipenv install sebagian besar adalah apa yang didapat #966, tetapi tidak persis sama. Bayangkan Anda memiliki X = "*" . Melakukan pipenv install X mungkin masih harus memutakhirkan X di file kunci, meskipun tidak ada perubahan pada Pipfile . Pipenv perlu melacak apa yang _sebenarnya_ diperbarui.

Dengan kata lain Anda tidak dapat sepenuhnya memisahkan "instal" dari "kunci". Lihat misalnya https://github.com/taion/pipf/blob/1feee35a2e4480bc7e5b53bfab17587d37bdf9dd/pipf/pipfile.py#L150 -L155 – saat membuat ulang lockfile, saya secara eksplisit memasukkan paket yang sedang diinstal untuk membuang batasan lama untuk itu .

Keluhannya bukanlah sesuatu seperti pipenv lock eksplisit memperbarui semua dependensi ke yang terbaru yang tersedia; itu pipenv install Y menyentuh versi untuk X . Dengan kata lain, orang seharusnya tidak perlu menjalankan pipenv lock --keep-outdated secara eksplisit.

Penanganan benang di sini adalah contoh yang cukup bagus dalam hal CLI. Benang memiliki yarn lockfile , yang menghasilkan file kunci tanpa mengubah apa pun, dan secara eksplisit ditandai sebagai "[tidak] diperlukan", dan memiliki yarn upgrade yang memutakhirkan semuanya. Jika karena alasan tertentu Anda mengedit dependensi Anda secara manual, langkah selanjutnya adalah menjalankan yarn install , yang keduanya memperbarui lockfile Anda (minimal) dan menginstal paket yang diperlukan.

Saya tidak pernah secara eksplisit membuat file kunci di luar menginstal dependensi saya yang diperbarui, dan saya tidak mengerti mengapa saya ingin melakukannya. Ini bukan tindakan biasa dengan manajer paket penguncian, karena hampir semua tindakan yang Anda lakukan untuk mengubah dependensi yang Anda instal akan tetap memperbarui file kunci. Kumpulan interaksi yang menghadap pengguna malah lebih terlihat seperti:

  1. Instal semua dependensi
  2. Tambahkan atau tingkatkan satu atau lebih dependensi tertentu
  3. Tingkatkan semua dependensi

(1) dan (2) harus selalu menerapkan sedikit perubahan pada file kunci saya (atau membuatnya jika perlu), sedangkan (3) pada dasarnya harus mengabaikan file kunci yang ada. Tetapi untuk hanya menghasilkan file kunci, (1) sudah cukup (karena itu akan dijalankan dari lingkungan dev tempat semuanya diinstal).

PS Yarn memisahkan yarn add (tambahkan ketergantungan) dari yarn install (instal semua dependensi). Agak membingungkan dan menjengkelkan pada awalnya, tetapi semakin saya menggunakannya, semakin saya menyukai perbedaan itu. Memiliki satu perintah install yang keduanya menambahkan dependensi spesifik _dan_ menginstal semua dependensi proyek agak aneh, jika Anda memikirkannya. Kedua tindakan itu bukanlah hal yang sama.

Beberapa paragraf pertama di https://lwn.net/Articles/711906/ menjelaskan pola pikir saya dengan cukup baik di sini: "target bergerak" harus menjadi model keamanan default untuk semua proyek, dan memilih keluar dari itu dan masuk ke Pendekatan "bunker yang diperkeras" harus menjadi keputusan desain yang disengaja yang diambil hanya setelah mempertimbangkan pertukarannya.

Oleh karena itu pilihan nama opsi juga: --keep-outdated tidak hanya terinspirasi oleh pip list --outdated , itu juga sengaja dipilih untuk terlihat meragukan di baris perintah (karena menjaga dependensi yang ketinggalan zaman secara inheren berbahaya dari perspektif keamanan).

Untuk kasus spesifik pipenv install X , seharusnya tidak melakukan upgrade secara implisit, karena pip install X tidak secara implisit melakukan upgrade.

pipenv saat ini tidak konsisten sehubungan dengan poin terakhir itu, karena ia melakukan hal berikut:

  • panggilan pip install package (tidak ada peningkatan implisit)
  • panggilan pipenv lock (peningkatan implisit)

Jadi ide untuk memastikan konsistensi dengan selalu menggunakan file kunci untuk mengarahkan instalasi (kecuali --skip-lock digunakan), dan menawarkan pipenv lock --keep-outdated untuk mencocokkan strategi peningkatan only-if-needed pip.

Saya pikir kita setuju pada poin-poin substantif tentang keinginan untuk meningkatkan dependensi.

Dan, tentu, pipenv install -U <package> untuk memperbarui satu paket akan lebih baik paralel dengan Pip.

Saya katakan, meskipun, dalam alur kerja normal, pengguna tidak memiliki alasan untuk menjalankan pipenv lock , dengan atau tanpa --keep-outdated atau apa pun. Kumpulan perintah yang mungkin dijalankan pengguna untuk berbagai skenario adalah:

  • Paket baru bootstrap: pipenv init
  • Menyiapkan tiruan proyek baru: pipenv install
  • Menambahkan ketergantungan baru: pipenv install <package> (dan perhatikan lagi bahwa Benang memanggil ini add , yang merupakan ide bagus)
  • Sinkronkan ulang dependensi yang diinstal setelah mengedit secara manual Pipfile : pipenv install
  • Memutakhirkan semua dependensi ke versi terbaru yang kompatibel: pipenv update

Semua tindakan di atas membuat Pipfile.lock sinkron.

Atau, dengan kata lain, saya tidak pernah harus menjalankan npm shrinkwrap (dengan npm 5), dan saya tidak pernah harus menjalankan yarn lockfile .

(Dan alasan mengapa tidak begitu berguna untuk hanya membuat file kunci dengan dependensi yang diperbarui adalah karena langkah selanjutnya dalam alur kerja dev adalah menginstal ulang dependensi yang diperbarui, lalu menjalankan rangkaian pengujian.)

FWIW, saya menjalankan alat yang membuat PR pembaruan ketergantungan secara otomatis ( Dependabot ), termasuk untuk Pipfiles, dan saya akan menyukai opsi pipenv lock --keep-outdated . Saat ini kami mengedit Pipfiles untuk mengunci setiap ketergantungan kecuali yang kami perbarui saat kami membuat PR.

Dalam pengalaman saya, PR untuk memperbarui satu ketergantungan jauh lebih mungkin untuk digabungkan daripada yang memperbarui banyak sekaligus. Menghasilkan mereka secara otomatis membantu memastikan target bergerak terus bergerak.

Benar, dan pembuatan PR adalah tempat yang menurut saya pipenv lock --keep-outdated akan berguna: ini mengasumsikan langkah "pipenv install && jalankan tes" akan terjadi dari jarak jauh di server CI, bukan di mesin tempat PR dibuat. Demikian pula, pipenv lock adalah untuk kasus di mana Anda bertujuan untuk menghasilkan pembaruan batch PR yang akan Anda uji di CI, tanpa terlalu khawatir tentang menerapkan perubahan secara lokal.

Dalam nada itu, jika pipenv install <requirement> menjadi setara dengan "update Pipfile + pipenv lock --keep-outdated + pipenv install ", maka masuk akal jika pipenv update menjadi setara ke pipenv lock && pipenv install .

Sementara yarn membuat perbedaan antara yarn install dan yarn add , jika kita ingin menambahkan perbedaan seperti itu ke pipenv , saya akan lebih cenderung untuk meminjam dari terminologi pip-tools dan tambahkan perintah pipenv sync untuk mengatakan "Jadikan lingkungan saat ini cocok dengan file kunci". Namun, melakukan itu di luar cakupan proposal ini: ini harus berfokus secara khusus pada menghilangkan peluang munculnya perbedaan antara dependensi penerapan dan dependensi pengembangan.

@greysteil

Setara untuk Greenkeeper/&c. use case dengan npm hanya sebagai berikut, bukan?

$ npm install --package-lock-only <package><strong i="8">@latest</strong>

Sebenarnya apakah npm5 bahkan mengekspos cara untuk _just_ membuat package-lock.json luar npm install ?

@ncoghlan

Layanan seperti penjaga hijau sangat keren dan layak digunakan, tetapi akan aneh untuk mempertimbangkan bahwa kasus penggunaan inti (dan seperti disebutkan di atas, bahkan kasus "perbarui satu ketergantungan dan file kunci, tetapi jangan instal sesuatu" mengakui ekspresi yang lebih bersih).

Ups, saya menekan enter terlalu cepat. Di luar alur kerja gaya Greenkeeper, hampir tidak biasa _just_ menabrak dependensi saya tanpa menyinkronkannya secara lokal. Masuk akal jika Anda entah bagaimana tidak menginstal salinan lokal dari deps. Dan sekali lagi layanan khusus PR adalah pengecualian, tetapi hanya itu.

Deskripsi di sini adalah "Alur Kerja Pengembangan Python untuk Manusia ", dan karena itu perlu diingat seperti apa alur kerja pengembangan yang sebenarnya. Dan kami memiliki bukti keberadaan yang cukup bagus bahwa menjalankan operasi "generate lockfile" secara eksplisit hampir tidak pernah diperlukan, jadi sebaiknya jangan terlalu memikirkannya.


Masalah khusus di sini, BTW, adalah bahwa Pipenv menggunakan rentang * secara default. Jika saya melakukannya pipenv install flask , saya mendapatkan flask = "*" di Pipfile . Artinya, jika saya ingin memutakhirkan versi Flask yang saya instal dengan cara yang bersih, perubahan semacam itu ingin menjadi perubahan hanya-lockfile.

Sebuah operasi upgrade bisa di saklar prinsip * persyaratan ke >= jangkauan atau sesuatu di Pipfile , tapi yang menciptakan asimetri aneh antara "upgrade" dan "install awal". Bisa dibilang resolusi terbaik di sini mungkin menggunakan rentang >= untuk pemasangan awal. Setidaknya, saya tidak yakin saya dapat melihat alasan bagus untuk menggunakan rentang * sana.

@taion - ya, setuju, tidak mengharapkan kalian untuk mengingat kami / alat pembaruan ketergantungan lainnya terlalu banyak, meskipun sangat berterima kasih jika Anda melakukannya! Saya hanya menyebutkannya karena saya tahu saya akan menggunakan pipenv lock --keep-outdated secara manual jika saya telah memperbarui dependensi di tempat kerja saya sebelumnya (kami memiliki satu PR per kebijakan pembaruan dependensi).

Untuk referensi, npm menambahkan opsi package-lock-only dalam rilis terbaru ( changelog ).

@greysteil Apa yang Anda lakukan jika seseorang memiliki kisaran * di Pipfile ? Seperti pada contoh flask = "*" atas. Apa adanya, mengingat ini adalah cara Pipenv menambahkan dependensi secara default, Anda perlu mengetahui persyaratan mana yang harus dilepas pin saat membangun kembali file kunci, bukan?

_Saya tidak mengerti cara kerja Pipenv di dekat detail yang dilakukan orang lain di utas ini, dan tidak ingin mengeluarkannya dari topik. Jika di bawah ini bermanfaat, bagus. Jika tidak, maaf!_

Kami menggunakan beberapa tipuan jahat:

  • Untuk menemukan versi yang akan diperbarui, saat ini kami hanya mendapatkan versi terbaru (kita harus menggunakan resolver di pip-tool , tetapi belum. Ternyata itu tidak terlalu buruk karena langkah selanjutnya akan error jika tidak dapat diselesaikan )
  • Untuk menghasilkan Pipfile.lock yang hanya memperbarui ketergantungan (tingkat atas), kami

    1. Perbarui entri Pipfile untuk ketergantungan yang kami perbarui untuk mendukung versi terbaru

    2. Parsing file kunci yang ada

    3. Perbarui Pipfile untuk mengatur persyaratan pada setiap ketergantungan lain dengan apa yang diselesaikannya di lockfile

    4. Jalankan pipenv lock untuk menghasilkan file kunci baru

    5. Perbarui hash di file kunci yang baru dibuat menjadi seperti apa jadinya jika kita tidak melakukan langkah 3 (peretasan mengerikan yang benar-benar ingin saya hapus)

Hasil akhirnya adalah pengguna mendapatkan PR dengan Pipfile tidak berubah (jika persyaratannya adalah * ) tetapi Pipfile.lock diperbarui untuk menggunakan versi terbaru dari ketergantungan itu.

Seperti yang saya pahami, pipenv lock --keep-outdated akan memungkinkan saya untuk menggunakan aliran berikut sebagai gantinya:

  1. Perbarui persyaratan pada ketergantungan yang kami perbarui agar sama dengan versi terbaru
  2. Jalankan pipenv lock --keep-outdated untuk menghasilkan file kunci baru
  3. Perbarui hash di file kunci yang baru dibuat menjadi seperti apa jadinya jika kami hanya memperbarui Pipfile untuk mendukung versi terbaru

Jadi, itu akan lebih baik. Ideal untuk dapat menjalankan pipenv lock --keep-outdated <some_package_name> , tetapi pengemis tidak bisa memilih! :gurita:

Misalkan Pipfile saya memiliki:

flask = "*"
numpy = "*"

flask transitif tergantung pada werkzeug . Misalkan ada pemutakhiran yang tersedia untuk flask dan numpy , dan saya ingin memutakhirkan versi flask , tetapi tidak memutakhirkan versi numpy .

Jika saya tidak menggunakan Pipenv, saya hanya menjalankan:

$ pip install -U flask
$ pip freeze > requirements.txt

Jika saya menggunakan pip-tools, saya akan menjalankan:

$ pip-compile -P flask
$ pip-sync # Or: pip install -r requirements.txt

Yah, hanya melakukan beberapa hipotetis pipenv lock --keep-outdated tidak akan melakukan apa-apa. Di sisi lain, membangun kembali lockfile sepenuhnya akan meningkatkan NumPy juga.

Tetapi kecuali saya salah paham, strategi yang Anda jelaskan di atas hanya akan memperbarui versi flask di lockfile, tetapi bukan versi werkzeug . Ini mungkin merupakan kumpulan dependensi yang tidak valid, jika versi baru flask juga _memerlukan_ versi baru werkzeug .

Dengan demikian, untuk kasus ini, yang menurut saya merupakan kasus penggunaan yang sangat umum untuk manusia yang meningkatkan dependensi, harus ada beberapa cara untuk memutakhirkan satu paket dan dependensi transitifnya (jika diperlukan), tetapi tidak yang lain.

Masalahnya di sini secara khusus adalah dependensi * . Cara npm menangani ini adalah memulai dengan sesuatu seperti:

flask = ">=0.12.1"

Dan kemudian saat meminta peningkatan, tekan itu ke:

flask = ">=0.12.2"

Dalam hal ini strategi di atas menjalankan sesuatu seperti pipenv lock --keep-outdated akan melakukan hal yang benar. Tetapi jika Anda menggunakan rentang * , maka saya tidak melihat cara nyata untuk melakukan ini tanpa beberapa alat khusus seperti pipenv install -U flask , yang kemudian turun flask secara khusus sebagai pin yang disarankan saat membangun kembali file kunci.

Maaf, saya tidak cukup jelas tentang langkah (iii) di atas. Kami mengunci semua dependensi tingkat atas ke versi di file kunci, tetapi membiarkan sub-dependensi tidak terkunci.

@greysteil saya mengerti - jadi ini berpotensi meningkatkan dependensi transitif dari dependensi langsung lainnya?

Ya - teorinya adalah jika dependensi tingkat atas Anda menentukan sub-dependensinya dengan benar (yaitu, secara pesimis), maka memperbarui sub-dependensi Anda seharusnya tidak berbahaya.

(Saya lebih suka perilakunya lebih dekat dengan Ruby's Bundler, di mana hanya sub-dependensi dari dependensi yang diperbarui juga dapat diperbarui, tetapi pipenv yang kuat untuk melakukan itu tampaknya tidak sepadan dengan peretasan.)

@taion Secara desain, pipenv berfokus hampir seluruhnya pada model keamanan "target bergerak" yang saya jelaskan dalam pembicaraan LCA saya. Dengan demikian, dua model penggunaan yang dimaksud adalah sebagai berikut:

  • Pembaruan batch interaktif:

    • Seorang manusia secara berkala melakukan beberapa tindakan (pembaruan batch eksplisit, menambahkan ketergantungan baru, meningkatkan ketergantungan eksplisit)
    • Sebagai bagian dari operasi ini, file kunci dan lingkungan saat ini diperbarui ke versi terbaru dari semua yang memenuhi batasan yang dinyatakan dalam Pipfile
    • Seiring waktu, batasan yang diungkapkan diperbarui (dan dependensi yang dipilih dialihkan) hingga cara kerja ini menjadi tidak menyakitkan, atau pengembang beralih ke opsi kedua di bawah
  • Pembaruan selektif otomatis:

    • Proses otomatis mengawasi versi baru dependensi dan mengirimkan masalah+PR kapan pun tersedia
    • Manusia terutama mengatur lingkungan baru, secara eksplisit menambahkan dependensi, dan menyesuaikan batasan yang diungkapkan pada dependensi yang ada

Sekarang, saat ini ada masalah desain & implementasi CLI yang memengaruhi kedua model penggunaan tersebut - untuk pembaruan batch interaktif, ada cara agar file kunci dan lingkungan lokal tidak sinkron, dan untuk pembaruan selektif otomatis, ada tantangan dalam mengimplementasikan alat yang melakukan pembaruan selektif, serta memungkinkan operasi selektif interaktif terkait untuk menambahkan dependensi baru dan memodifikasi batasan pada yang sudah ada.

Tetapi filosofi desain inti "Default untuk menjalankan versi terbaru dari semuanya kecuali secara eksplisit diberitahu sebaliknya dalam Pipfile " tidak akan berubah - kami hanya ingin menambahkan dukungan pembaruan selektif yang cukup untuk menangani kasus di mana sebagian besar pembaruan file kunci dikirimkan oleh layanan manajemen pembaruan, bukan dikirim oleh manusia.

Luar biasa membaca bahwa alat otomatis adalah kasus penggunaan yang Anda pikirkan tentang @ncoghlan. 🎉

Jika Anda menginginkan umpan balik tentang apa yang Dependabot / orang lain inginkan / butuhkan, beri tahu saya. Python bukan bahasa rumah saya, jadi saya belum dapat berkontribusi ke pip/pipenv, tetapi saya ingin membantu dengan cara apa pun yang saya bisa.

@ncoghlan Saya sepenuhnya setuju dengan Anda di sini, dan saya pikir pendekatan yang Anda jelaskan masuk akal. Menggunakan LocalRequirementsRepository tidak terlalu sulit untuk diterapkan dari perspektif kode dan ini sejalan dengan pemikiran saya tentang proyek juga, dan diskusi ini sangat produktif

@techalchemy Oke, saya akan merevisi posting awal untuk membahas proposal simetris (yaitu menangani instalasi paket baru melalui pipenv lock --keep-outdated + pipenv install --ignore-pipfile , daripada menjalankan instalasi terlebih dahulu seperti yang kita lakukan sekarang) .

Itu masih akan meninggalkan kita dengan beberapa pertanyaan terbuka (seperti bagaimana --skip-lock harus bekerja dalam model itu), tetapi itu sudah cukup untuk mulai memecah permintaan fitur individual (seperti menambahkan --keep-outdated ke pipenv lock untuk meminta strategi peningkatan hanya jika diperlukan)

Oke, saya telah memperbarui posting awal dengan beberapa sub-langkah yang diusulkan yang akan memungkinkan kita untuk mencapai keadaan di mana benar-benar sulit untuk mendapatkan file kunci dan lingkungan lokal tidak sinkron.

Dari sublangkah yang diusulkan, saya pikir subperintah pipenv sync dan opsi pipenv lock --keep-outdated sudah cukup jelas bagi orang-orang yang tertarik untuk mengimplementasikannya, tetapi gagasan untuk mendefinisikan ulang semantik dari semua operasi lainnya yang mungkin menginstal atau memperbarui paket dalam hal pengeditan Pipfile dan perilaku pipenv lock dan pipenv sync kemungkinan memerlukan diskusi lebih lanjut.

Tampak hebat. Pada pertanyaan terbuka, saya sepenuhnya setuju dengan perilaku yang diusulkan untuk pip install --selective-upgrade <package> (yaitu, melakukan peningkatan yang menghormati batasan versi yang ada, kecuali diberikan yang baru). Itu perilaku yang sering Anda inginkan saat memperbarui satu paket - Saya dapat membayangkan orang menjalankan pip install --selective-upgrade django mana Anda memiliki batasan < 2.0 yang ingin Anda hormati.

Patut diklarifikasi beberapa salinan di atas – pipenv install --selective-upgrade diusulkan harus kira-kira identik dengan standar pip install -U .

Dan, sekali lagi, dalam praktiknya, orang banyak memikirkan hal ini dalam membangun pengelola paket lainnya. Mungkin dalam ruang hampa, alur kerja yang Anda gambarkan di https://github.com/pypa/pipenv/issues/1255#issuecomment -355435921 masuk akal, tetapi, seperti, tujuan di sini untuk membangun "Alur Kerja Pengembangan Python untuk Manusia", atau untuk bereksperimen dengan alur kerja pengembangan baru?

Pipenv adalah proyek yang sangat keren yang membuat banyak hal menjadi lebih baik, tetapi saya pikir ada kebingungan yang cukup mendasar dalam tujuan di sini. Mengunci manajer paket cukup standar akhir-akhir ini, dan sangat bagus bahwa Python akan diberkati, tetapi saya tidak berpikir menggabungkan "menjelajahi alur kerja manajemen paket teoretis baru" dan "membangun alur kerja manajemen paket yang berperilaku seperti yang diharapkan orang " adalah positif.

Sekali lagi, perhatikan misalnya http://bundler.io/v1.16/man/bundle-install.1.html#CONSERVATIVE -UPDATING dan banyak lagi lainnya.

Apa yang akan mengubah pikiran saya di sini adalah jika Anda dapat membuktikan bahwa Anda telah bekerja secara ekstensif dengan beberapa alat yang ada, dan menemukan alur kerja dev kurang. Namun, saya dapat memberi tahu Anda bahwa sebagai manusia, melihat Pipenv menerapkan default yang tidak biasa ini, apa pun alasannya, tidak membuat DX yang menyenangkan.

Untuk membuat tes lakmus itu lebih eksplisit:

  1. Apakah Anda sering menggunakan alat seperti npm, Yarn, atau Bundler?
  2. Jika demikian, apakah itu menyebabkan Anda mengalami masalah bahwa npm i , yarn add , dan bundle update <gem> / bundle add tidak menyentuh semua dependensi Anda yang lain?
  3. Apakah Anda merasa berat untuk menjalankan npm up , yarn upgrade , atau bundle update ?

Jika tidak, maka pada dasarnya tujuan default di sini tampaknya adalah dakwah untuk alur kerja baru, daripada membangun alat yang akan berfungsi seperti yang diharapkan pengguna.

Kalau tidak, ini sepertinya latihan dengan sengaja memilih default tak terduga yang di internet hanya akan membuat pengguna frustrasi – bukan yang diharapkan dari paket yang menggambarkan dirinya sebagai "untuk manusia".

@taion Ya, ini disengaja bahwa kami secara aktif mendorong orang-orang menuju pembaruan batch implisit dari semua dependensi mereka, dan ya, saya memiliki pengalaman luas dengan banyak manajer paket yang berbeda. Dalam pengalaman saya, konsekuensi dari default konvensional adalah bahwa orang secara teratur menjalankan versi kuno dari komponen yang mereka gunakan, tidak pernah memeriksanya untuk CVE, hanya memperbaruinya ketika komponen lain memaksa peningkatan, dan bahkan tidak menyadari bahwa pendekatan itu sangat bermasalah.

Jadi untuk pipenv , kami sengaja mengambil isyarat kami dari sistem operasi desktop seluler dan modern (yaitu default ke pembaruan otomatis yang memerlukan tindakan yang disengaja untuk menghindari), daripada mengikuti manajer paket lain dan sistem operasi server tradisional. Bukannya kami tidak tahu cara kerjanya - kami pikir hasil khas dari perilaku default tradisional itu buruk, dan kami ingin mencoba menghindarinya.

Menambahkan --keep-outdated (dan variabel lingkungan PIPENV_KEEP_OUTDATED=1 ) kemudian memungkinkan pengembang yang lebih berpengalaman untuk secara eksplisit mengatakan "Saya tahu apa yang saya lakukan, dan Anda dapat mempercayai saya untuk mengelola dependensi saya secara bertanggung jawab".

Saya telah menghapus pertanyaan terbuka --selective-upgrade , dan memasukkan detail itu ke dalam deskripsi fitur yang diusulkan itu.

Namun, saya telah menambahkan pertanyaan terbuka baru terkait dengan pipenv uninstall . Sementara saya siap untuk mempertahankan pipenv install menyiratkan pipenv update secara default (sesuai diskusi di atas dengan @taion), memiliki pipenv uninstall melakukan itu tampaknya kurang dapat dipertahankan bagi saya - memiliki operasi untuk menghapus dependensi yang berpotensi menambah dependensi transitif baru karena peningkatan pada komponen lain akan sangat aneh.

Pada pertanyaan terbuka, saya tidak dapat melihat kegunaan pipenv install --skip-lock dari dunia alat pembaruan ketergantungan otomatis. Jika tidak ada kasus penggunaan manusia (saya tidak bisa memikirkannya) maka saya pikir aman untuk menganggapnya berlebihan.

np menggunakan --no-package-lock (dan yang setara dengan Benang). Idenya adalah untuk menjalankan pengujian Anda dengan semua dependensi npm Anda tidak terkunci ke rentang terbaru yang kompatibel, secara eksplisit mengabaikan file kunci.

Kasus penggunaan khusus itu mungkin kurang relevan mengingat keberadaan tox (dan kesulitan membangun sesuatu seperti np untuk Python), meskipun demikian untuk sesuatu seperti perpustakaan, masuk akal untuk memiliki kedua set dependensi yang dikunci sehingga bahwa orang yang terjun tidak harus berurusan dengan lingkungan build yang rusak, dan untuk memungkinkan orang menguji dependensi kompatibel terbaru sebelum, misalnya, rilis.

Ya, saya pasti dapat melihat kasus penggunaan pengujian, tetapi bagian yang kurang jelas bagi saya adalah manfaat membiarkan lockfile tidak dimodifikasi dalam situasi itu (terutama karena pipenv update saat ini tidak menawarkan opsi itu):

  • jika itu murni untuk pengujian di CI, maka server CI tidak akan melakukan git push , jadi modifikasi lockfile tidak akan muncul di tempat lain
  • diberikan kontrol sumber, Anda dapat mengembalikan perubahan file kunci lokal apa pun jika Anda memutuskan tidak ingin menyimpannya

Ada juga pip install --upgrade <whatever> untuk melewati mekanisme penguncian dan batasan Pipfile yang dideklarasikan sepenuhnya.

Saat ini, opsi tersebut masuk akal, karena itu adalah nilai terdekat yang ditawarkan pipenv saat ini ke pipenv --keep-outdated (di mana Anda dapat menambahkan sesuatu ke Pipfile tanpa memperbarui semua yang lain secara otomatis).

Untuk saat ini, saya akan membiarkannya sebagai pertanyaan terbuka - jawaban yang benar diharapkan akan menjadi lebih jelas setelah pip lock --keep-outdated dan pip install --keep-outdated ada.

Apakah perubahan yang diusulkan masih diharapkan untuk memperbaiki perbedaan antara [packages] dan [dev-packages] ? Secara khusus, saya mengalami # 1220, yang mengacu pada masalah ini, tetapi saya tidak dapat melihat bagaimana perubahan yang diusulkan akan memperbaiki ketidakkonsistenan itu. Atau apakah inkonsistensi dev/non-dev berbeda dari yang dijelaskan di #1220 dan haruskah masalah itu diselidiki secara terpisah?

@matthijskooijman Tidak secara eksplisit dinyatakan di posting teratas, tetapi https://github.com/pypa/pipenv/issues/1255#issuecomment -354585775 (yang disebutkan dalam posting saat ini) menyatakan bahwa perlu ada cara untuk "mendeteksi (dan menyelesaikan) inkonsistensi" di packages dan dev-packages , atau diperlukan alternatif. Ini bagi saya menyiratkan bahwa inkonsistensi akan diselesaikan.

Tujuannya adalah agar ketidakkonsistenan itu diselesaikan pada langkah pipenv lock ( pipenv sync kemudian akan mewarisi file kunci yang konsisten sendiri)

(Catatan: ini tidak jelas sebelumnya, jadi saya telah menambahkan poin-poin terpisah yang memanggil langkah itu)

Saya baru menyadari bahwa pipenv tidak membuat ulang file kunci ketika Anda mengubah implementasi python yang mendasari antara CPython dan PyPy.

  1. Buat dan instal venv dengan pipenv install --python pypy
  2. hapus venv
  3. Buat dan instal venv lagi dengan pipenv install
  4. Lockfile tidak dibuat ulang dan bagian host-environment-markers akan tetap berisi "platform_python_implementation": "PyPy"

@joshfriend Itu sebenarnya disengaja, tetapi lihat https://github.com/pypa/pipenv/issues/857#issuecomment -368223561 untuk beberapa komentar tentang mengapa saat ini bermasalah.

Pertahankan perilaku saat ini untuk pemasangan pipenv tanpa argumen, tetapi beralihlah ke merekomendasikan penggunaan sinkronisasi pipenv saat menyiapkan lingkungan baru (dengan cara itu pemasangan pipenv digunakan terutama untuk mengubah komponen yang dipasang)

Saya pikir sekarang install memanggil sync , kami masih dapat mengizinkan pengguna menggunakan install untuk meningkatkan proyek baru.

perbarui kunci pipenv untuk selalu memastikan bahwa [paket] dan [paket dev] konsisten satu sama lain (resolusi untuk #1137)

saya baru saja mencoba ini https://github.com/pypa/pipenv/commit/fdebdc3c423dce83c13d4e384acb703291109f1e

ini memiliki detail implementasi yang pasti (sub deps yang ada untuk paket pengembangan tetapi bukan paket default yang tidak akan dihapus, misalnya), tetapi ini merupakan peningkatan yang pasti.

@kennethreitz Poin bagus tentang pipenv install membaca baik untuk kasus instalasi baru: itu hanya terbaca aneh dalam kasus sinkronisasi ulang, di mana ia mungkin akhirnya melakukan peningkatan dan penurunan versi untuk membuat versi cocok. Saya telah menandai poin penting tentang merekomendasikan pipenv sync sebagai selesai, dan membahas bagian-bagian yang kami putuskan untuk tidak diubah.

Dengan penerapan perubahan #1137 Anda, itu hanya menyisakan peningkatan --keep-outdated dan --selective-upgrade yang bersama-sama mengimplementasikan #966.

Mengingat pendekatan implementasi yang dipilih untuk #1486, fitur --selective-upgrade akan perlu meneruskan --upgrade-strategy=only-if-needed ke panggilan pip install mendasari selain pengaturan keep_outdated ketika memperbarui file kunci yang kedaluwarsa.

Bekerja pada --keep-outdated sekarang :)

$ pipenv lock --keep-outdated sekarang mempertahankan semua nomor versi dari file kunci sebelumnya, kecuali nomor versi disematkan.

Juga menambahkan opsi konfigurasi Pipfile (saat ini kami hanya memiliki allow_prereleases ): keep_outdated :

[pipenv]

keep_outdated = true

--selective-upgrade selesai.

Sabas! Menutup ini, karena batasan lebih lanjut yang belum tercakup oleh #857 dapat dilaporkan sebagai masalah baru setelah 10.1 dirilis :)

sedang mengerjakan bug, tetapi akan segera diselesaikan

tetap

Apakah halaman ini membantu?
0 / 5 - 0 peringkat