Kapan menggunakan file persyaratan pip versus install_requires di setup.py?

94

Saya menggunakan pip dengan virtualenv untuk mengemas dan menginstal beberapa pustaka Python.

Saya membayangkan apa yang saya lakukan adalah skenario yang cukup umum. Saya adalah pengelola beberapa pustaka yang dependensinya dapat saya tentukan secara eksplisit. Beberapa perpustakaan saya bergantung pada perpustakaan pihak ketiga yang memiliki ketergantungan transitif yang tidak dapat saya kendalikan.

Apa yang saya coba capai adalah pip installsalah satu perpustakaan saya mengunduh / menginstal semua dependensi upstreamnya. Apa yang saya perjuangkan dalam dokumentasi pip adalah jika / bagaimana file persyaratan dapat melakukan ini sendiri atau jika mereka benar-benar hanya pelengkap untuk digunakan install_requires.

Apakah saya akan menggunakan install_requiresdi semua pustaka saya untuk menentukan dependensi dan rentang versi, lalu hanya menggunakan file persyaratan untuk menyelesaikan konflik dan / atau membekukannya untuk build produksi?

Anggap saja saya hidup di dunia imajiner (saya tahu, saya tahu) dan ketergantungan hulu saya langsung dan dijamin tidak akan pernah bertentangan atau merusak kompatibilitas ke belakang. Apakah saya akan dipaksa untuk menggunakan file persyaratan pip sama sekali atau biarkan pip / setuptools / distribusikan menginstal semuanya berdasarkan install_requires?

Ada banyak pertanyaan serupa di sini, tetapi saya tidak dapat menemukan pertanyaan yang mendasar seperti kapan harus menggunakan satu atau yang lain atau menggunakan keduanya bersama-sama secara harmonis.

Joe Holloway
sumber
3
Ini adalah artikel yang sangat bagus yang menjelaskan hubungan keduanya, dan juga bagaimana mereka berintegrasi.
Björn Pollex

Jawaban:

68

Filosofi saya adalah itu install_requiresharus menunjukkan minimal apa yang Anda butuhkan. Ini mungkin termasuk persyaratan versi jika Anda tahu bahwa beberapa versi tidak akan berfungsi; tetapi seharusnya tidak memiliki persyaratan versi di mana Anda tidak yakin (misalnya, Anda tidak yakin apakah rilis dependensi di masa mendatang akan merusak perpustakaan Anda atau tidak).

Persyaratan file di sisi lain harus menunjukkan apa yang Anda tahu tidak bekerja, dan mungkin termasuk dependensi opsional yang Anda rekomendasikan. Misalnya Anda mungkin menggunakan SQLAlchemy tetapi menyarankan MySQL, dan letakkan MySQLdb di file persyaratan).

Jadi, ringkasannya: install_requiresadalah menjauhkan orang dari hal-hal yang Anda tahu tidak berfungsi, sementara file persyaratan untuk mengarahkan orang ke hal-hal yang Anda tahu berhasil. Salah satu alasannya adalah install_requirespersyaratan selalu dicentang, dan tidak dapat dinonaktifkan tanpa benar-benar mengubah metadata paket. Jadi, Anda tidak dapat dengan mudah mencoba kombinasi baru. File persyaratan hanya diperiksa pada saat penginstalan.

Ian Bicking
sumber
5
apakah ini berarti Anda harus mencerminkan setup.py install_requires=deps requirements.txt?
proppy
9
Memiliki keduanya, persyaratan di setup.py dan file persyaratan berbahaya, karena duplikasi hanya meminta untuk tidak sinkron.
Sebastian Blask
1
Juga, bagaimana Anda benar-benar bekerja dengannya? Saya berasumsi, Anda menggunakan file persyaratan sekali untuk mencapai keadaan yang pasti berfungsi. Kemudian instal dengan paket sebenarnya dengan pip. Anda tidak akan pernah bisa menggunakan -Ukarena itu mungkin menimpa dependensi dari file persyaratan? Bagaimana Anda meningkatkan?
Sebastian Blask
1
Apakah jawaban ini berlaku sama untuk aplikasi dan paket? Bayangkan aplikasi-web-saya (aplikasi) bergantung pada beberapa-alat (paket), yang keduanya bergantung pada paket permintaan. Jika some-tool memiliki file requirement.txt yang menyematkan versi atau rentang versi tertentu dari permintaan, itu tampaknya akan menimbulkan masalah potensial untuk aplikasi-web-saya, yang mungkin telah menentukan rentang versi / versi yang bertentangan.
Reece
2
Seharusnya hanya ada cara untuk menginstal paket. Jadi, memiliki keduanya tidak disarankan kecuali Anda ingin membingungkan kontributor lainnya.
Gewthen
18

inilah yang saya masukkan ke setup.py saya:

# this grabs the requirements from requirements.txt
REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]

setup(
    .....
    install_requires=REQUIREMENTS
)
rbp
sumber
20
Hati-hati, file persyaratan dapat berisi komentar dan inklusi. Anda harus menggunakan parser pip
Romain Hardouin
1
ya, saya akhirnya mengubahnya untuk menghapus komentar. pip parser terlihat lebih baik dari jawaban saya.
rbp
7
Mengapa menggunakan file persyaratan jika semua isinya sudah ada di setup.py?
Sebastian Blask
2
@RomainHardouin, seperti yang disebutkan dalam komentar ke jawaban tertaut Anda, pip tidak dimaksudkan untuk digunakan seperti itu.
akaihola
1
ya ini bekerja untuk saya sampai kritis --extra-index-urldalam persyaratan diperlukan dan ini meledak di wajah saya. Terima kasih @RomainHardin
Tommy
11

Panduan Pengguna Kemasan Python memiliki halaman tentang topik ini, saya sangat menyarankan Anda membacanya:

Ringkasan:

install_requiresada di sana untuk membuat daftar dependensi dari paket yang mutlak harus diinstal agar paket dapat bekerja. Ini tidak dimaksudkan untuk menyematkan dependensi ke versi tertentu, tetapi rentang diterima, misalnya install_requires=['django>=1.8']. install_requiresdiamati oleh pip install name-on-pypidan alat lainnya.

requirements.txthanyalah file teks, yang dapat Anda pilih untuk dijalankan pip install -r requirements.txt. Ini dimaksudkan untuk memiliki versi dari semua dependensi dan subdependencies disematkan, seperti ini: django==1.8.1. Anda dapat membuatnya menggunakan pip freeze > requirements.txt. (Beberapa layanan, seperti Heroku, berjalan secara otomatis pip install -r requirements.txtuntuk Anda.) pip install name-on-pypiTidak melihat requirements.txt, hanya pada install_requires.

Flimm
sumber
5

Saya hanya pernah menggunakan setup.pydan install_requireskarena hanya ada satu tempat untuk dilihat. Ini sama kuatnya dengan memiliki file persyaratan dan tidak ada duplikasi untuk dipertahankan.

Sebastian Blask
sumber
Pertanyaannya adalah kapan harus menggunakan satu atau yang lain, saya tidak mengejanya, tetapi jawaban saya mengatakan bahwa saya selalu menggunakan satu dan tidak pernah yang lain. Bagaimana itu tidak menjawab pertanyaannya?
Sebastian Blask