Saya memiliki requirements.txt
file yang saya gunakan dengan Travis-CI. Tampaknya konyol untuk menduplikasi persyaratan di keduanya requirements.txt
dan setup.py
, jadi saya berharap untuk menyerahkan file handle ke install_requires
kwarg di setuptools.setup
.
Apakah ini mungkin? Jika demikian, bagaimana cara saya melakukannya?
Ini requirements.txt
file saya :
guessit>=0.5.2
tvdb_api>=1.8.2
hachoir-metadata>=1.3.3
hachoir-core>=1.3.3
hachoir-parser>=1.3.4
install_requires
digunakan untuk mendeklarasikan dependensi pada paket yang diperlukan agar paket bekerja dan digunakan oleh pengembang paket, sementararequirements.txt
digunakan untuk mengotomatiskan penginstalan lingkungan, yang memungkinkan menginstal perangkat lunak tambahan dan melakukan penginstalan versi dan digunakan oleh sysadmin yang menyebarkan paket. Peran dan target audiens mereka berbeda secara signifikan, jadi mencoba menggabungkannya seperti keinginan OP adalah kesalahan desain yang sebenarnya.[line.strip() for line in open("requirements.txt").readlines()]
?pkg_resources.parse_requirements()
Jawaban:
Anda dapat membalikkannya dan mendaftar dependensi
setup.py
dan memiliki karakter tunggal - titik.
-requirements.txt
sebagai gantinya.Atau, bahkan jika tidak disarankan, masih mungkin untuk mengurai
requirements.txt
file (jika tidak merujuk persyaratan eksternal dengan URL) dengan hack berikut (diuji denganpip 9.0.1
):Ini tidak memfilter penanda lingkungan .
Di versi lama pip, lebih khusus lebih tua dari 6.0 , ada API publik yang dapat digunakan untuk mencapai hal ini. File persyaratan dapat berisi komentar (
#
) dan dapat menyertakan beberapa file lainnya (--requirement
atau-r
). Jadi, jika Anda benar-benar ingin mem-parsing,requirements.txt
Anda dapat menggunakan pip parser:sumber
setup(..., dependency_links=[str(req_line.url) for req_line in parse_requirements(<requirements_path>)], ...)
pip
default untuk mem-parsing dependensi darisetup.py
ketiadaanrequirements.txt
, jawaban sederhana yang dicatat oleh Tobu di bawah ini adalah daftar semua dependensi di dalamsetup.py
dan hapusrequirements.txt
. Untuk aplikasi yang membutuhkan keduanya, cukup kurangi daftar dependensirequirements.txt
menjadi hanya.
karakter. SelesaiDi muka itu, tampaknya itu
requirements.txt
dansetup.py
merupakan duplikat yang konyol, tetapi penting untuk dipahami bahwa walaupun bentuknya serupa, fungsi yang dimaksud sangat berbeda.Tujuan dari pembuat paket, ketika menentukan dependensi, adalah untuk mengatakan "di mana pun Anda menginstal paket ini, ini adalah paket lain yang Anda butuhkan, agar paket ini berfungsi."
Sebaliknya, penulis penyebaran (yang mungkin orang yang sama pada waktu yang berbeda) memiliki pekerjaan yang berbeda, di mana mereka mengatakan "inilah daftar paket yang telah kami kumpulkan dan uji coba dan sekarang saya perlu menginstal".
Penulis paket menulis untuk berbagai skenario, karena mereka meletakkan pekerjaan mereka di luar sana untuk digunakan dengan cara yang mungkin tidak mereka ketahui, dan tidak memiliki cara untuk mengetahui paket apa yang akan diinstal bersama paket mereka. Untuk menjadi tetangga yang baik dan menghindari konflik versi dependensi dengan paket lain, mereka perlu menentukan berbagai versi dependensi yang mungkin dapat berfungsi. Inilah yang
install_requires
disetup.py
lakukan.Penulis penyebaran menulis untuk tujuan yang sangat berbeda, sangat spesifik: satu contoh aplikasi atau layanan yang diinstal, diinstal pada komputer tertentu. Untuk mengontrol penyebaran secara tepat, dan memastikan bahwa paket yang tepat diuji dan digunakan, penulis penyebaran harus menentukan versi yang tepat dan lokasi-sumber dari setiap paket yang akan diinstal, termasuk dependensi dan dependensi dependensi. Dengan spek ini, penyebaran dapat diulangi pada beberapa mesin, atau diuji pada mesin uji, dan penulis pemasangan dapat yakin bahwa paket yang sama digunakan setiap waktu. Inilah yang dilakukan seorang
requirements.txt
.Jadi Anda dapat melihat bahwa, walaupun keduanya terlihat seperti daftar besar paket dan versi, kedua hal ini memiliki pekerjaan yang sangat berbeda. Dan tentu saja mudah untuk mencampur ini dan membuatnya salah! Tetapi cara yang tepat untuk memikirkan hal ini adalah itu
requirements.txt
adalah "jawaban" untuk "pertanyaan" yang diajukan oleh persyaratan di semuasetup.py
file paket yang beragam . Alih-alih menulisnya dengan tangan, sering dihasilkan dengan memberi tahu pip untuk melihat semuasetup.py
file dalam satu set paket yang diinginkan, menemukan satu set paket yang dianggapnya sesuai dengan semua persyaratan, dan kemudian, setelah diinstal, "membekukan "daftar paket itu menjadi file teks (ini adalah asalpip freeze
nama itu).Jadi takeaway:
setup.py
harus mendeklarasikan versi dependensi yang paling longgar yang masih bisa diterapkan. Tugasnya adalah untuk mengatakan apa yang bisa digunakan paket tertentu.requirements.txt
adalah manifes penyebaran yang mendefinisikan seluruh pekerjaan instalasi, dan tidak boleh dianggap terikat pada satu paket. Tugasnya adalah untuk mendeklarasikan daftar lengkap dari semua paket yang diperlukan untuk melakukan penyebaran.Referensi:
sumber
requirements.txt
bersama dengan sumber paket yang berisi persyaratan beton / beku untuk instalasi atau pengujian. Tentunyasetup.py
dapat digunakan untuk tujuan ini dalam proyek itu sendiri? Saya hanya bisa membayangkan menggunakan file seperti itu untuk alat-alat yang digunakan untuk mendukung mengelola proyek (misalnya refactoring, membuat rilis, dll.).requirements.txt
adalah lebih banyak dokumentasi untuk keadaan dunia yang menghasilkan bangunan tertentu, meskipun biasanya tidak digunakan dalam proses pembangunan itu sendiri? Itu masuk akal. Namun, sepertinya beberapa sistem bergantung pada duplikasi: Travis menginstal beberapa paket default (lama) di virtualenv Anda dan mengatakan untuk menggunakannyarequirements.txt
. Jika saya bertanya bagaimana memastikan dependensi menggunakan terbarusetup.py
, orang bersikeras bahwa saya harus menggunakanrequirements.txt
.Tidak dapat menangani file. The
install_requires
Argumen dapat hanya berupa string atau daftar string .Anda dapat, tentu saja, membaca file Anda di skrip setup dan meneruskannya sebagai daftar string
install_requires
.sumber
install_requires
. Namun, itu tidak berfungsi jika Anda tidak menggunakan sintaks deklaratif.setup.py
adalah program yang harus dijalankan, bukan file data yang harus diuraikan. Itu tidak membuat jawaban ini lebih buruk.include requirements.txt
ke dalamMANIFEST.in
atau Anda tidak akan dapat menginstal perpustakaan Anda dari distribusi sumber.File persyaratan menggunakan format pip yang diperluas, yang hanya berguna jika Anda perlu melengkapi Anda
setup.py
dengan kendala yang lebih kuat, misalnya menentukan url yang tepat dari mana beberapa dependensi harus berasal, atau outputpip freeze
untuk membekukan seluruh paket yang disetel untuk diketahui bekerja versi. Jika Anda tidak membutuhkan kendala tambahan, gunakan hanya asetup.py
. Jika Anda merasa perlu mengirim barangrequirements.txt
, Anda bisa membuatnya menjadi satu baris:Itu akan valid dan merujuk tepat ke konten
setup.py
yang ada di direktori yang sama.sumber
pip install -r requirements.txt
) tanpa menginstal paket itu sendiri?-e .
sudah cukup. Periksa halaman ini: caremad.io/posts/2013/07/setup-vs-requirementMeskipun bukan jawaban yang tepat untuk pertanyaan ini, saya merekomendasikan posting blog Donald Stufft di https://caremad.io/2013/07/setup-vs-requirement/ untuk mendapatkan jawaban yang bagus tentang masalah ini. Saya telah menggunakannya untuk kesuksesan besar.
Singkatnya,
requirements.txt
bukanlahsetup.py
alternatif, tetapi pelengkap penempatan. Simpan abstraksi yang sesuai dari dependensi paketsetup.py
. Tetapkanrequirements.txt
atau lebih dari mereka untuk mengambil versi tertentu dari dependensi paket untuk pengembangan, pengujian, atau produksi.Misalnya dengan paket yang termasuk dalam repo di bawah
deps/
:pip mengeksekusi paket
setup.py
dan menginstal versi dependensi spesifik yang dideklarasikan padainstall_requires
. Tidak ada duplikasi dan tujuan kedua artefak dipertahankan.sumber
pip install my-package
. Jika dependensi untuk paket saya tidak terdaftar di paket saya / setup.py, mereka tidak diinstal olehpip install my-package
. Saya tidak dapat menentukan cara menyediakan paket untuk orang lain yang menyertakan dependensi tanpa secara eksplisit menyatakannya di setup.py. Ingin tahu apakah seseorang telah menemukan cara untuk tetap KERING sambil memungkinkan orang lain untuk menginstal dependensi paket-saya + tanpa mengunduh file persyaratan dan menelepon secara manualpip install -r my-package/requirements.txt
.requirements.txt
. Itulah intinya. Memperbarui pertanyaan untuk memperjelas segalanya. Juga memperbarui tautan posting blog yang sudah usang.Penggunaan
parse_requirements
bermasalah karena API pipa tidak didokumentasikan dan didukung secara publik. Di pip 1.6, fungsi itu sebenarnya bergerak, jadi penggunaan yang ada kemungkinan akan rusak.Cara yang lebih dapat diandalkan untuk menghilangkan duplikasi antara
setup.py
danrequirements.txt
untuk menentukan dependensi Anda disetup.py
dan kemudian dimasukkan-e .
ke dalamrequirements.txt
file Anda . Beberapa informasi dari salah satupip
pengembang tentang mengapa itu cara yang lebih baik tersedia di sini: https://caremad.io/blog/setup-vs-requirement/sumber
Sebagian besar jawaban lain di atas tidak berfungsi dengan versi API pip saat ini. Berikut adalah cara yang benar * untuk melakukannya dengan versi pip saat ini (6.0.8 pada saat penulisan, juga bekerja di 7.1.2. Anda dapat memeriksa versi Anda dengan pip -V).
* Benar, karena ini adalah cara menggunakan parse_requirements dengan pip saat ini. Mungkin masih bukan cara terbaik untuk melakukannya, karena, seperti yang dikatakan poster di atas, pip tidak benar-benar memelihara API.
sumber
Instal paket saat ini di Travis. Ini menghindari penggunaan
requirements.txt
file. Sebagai contoh:sumber
pip freeze
dan mengekspor file tersebut di suatu tempat sebagai artefak (seperti S3 atau sesuatu), maka Anda akan memiliki cara yang bagus untuk menginstal ulang secara tepat apa yang Anda inginkan. diuji.from pip.req import parse_requirements
tidak bekerja untuk saya dan saya pikir itu untuk baris kosong di requirement.txt saya, tetapi fungsi ini berfungsisumber
Jika Anda tidak ingin memaksa pengguna Anda untuk menginstal pip, Anda dapat meniru perilakunya dengan ini:
sumber
Antarmuka berikut menjadi usang di pip 10:
Jadi saya beralih hanya untuk parsing teks sederhana:
sumber
pathlib
variasi dari itu.Pendekatan sederhana ini membaca file persyaratan dari
setup.py
. Ini adalah variasi dari jawaban oleh Dmitiry S .. Jawaban ini hanya kompatibel dengan Python 3.6+.Per DS ,
requirements.txt
dapat mendokumentasikan persyaratan konkret dengan nomor versi tertentu, sedangkansetup.py
dapat mendokumentasikan persyaratan abstrak dengan rentang versi longgar.Di bawah ini adalah kutipan dari blog saya
setup.py
.Perhatikan bahwa
distutils.text_file.TextFile
akan menghapus komentar. Selain itu, menurut pengalaman saya, Anda tampaknya tidak perlu mengambil langkah khusus untuk membundel dalam file persyaratan.sumber
WASPADALAH TERHADAP
parse_requirements
PERILAKU!Harap dicatat bahwa
pip.req.parse_requirements
akan mengubah garis bawah menjadi garis putus-putus. Ini membuat saya marah selama beberapa hari sebelum saya menemukannya. Contoh menunjukkan:menghasilkan
sumber
[ir.req.unsafe_name for ir in req_deps if ir.req is not None]
Saya membuat fungsi yang dapat digunakan kembali untuk ini. Ini sebenarnya mem-parsing seluruh direktori file persyaratan dan menetapkannya ke extras_require.
Terbaru selalu tersedia di sini: https://gist.github.com/akatrevorjay/293c26fefa24a7b812f5
sumber
pip._internal
.. Jika Anda tidak menyediakan API eksternal yang dapat digunakan, maka Anda tidak boleh merusak semua itu yang menggunakan semua yang Anda berikan.Solusi lain yang mungkin ...
dan kemudian menggunakan ...
sumber
tree
berasal?Saya tidak akan merekomendasikan melakukan hal seperti itu. Seperti yang disebutkan beberapa kali
install_requires
danrequirements.txt
jelas tidak seharusnya menjadi daftar yang sama. Tetapi karena ada banyak jawaban menyesatkan yang melibatkan API internal swasta dari pip , mungkin ada baiknya mencari alternatif yang lebih waras ...Tidak perlu pip untuk mem-parsing
requirements.txt
file dari skrip setuptoolssetup.py
. Proyek setuptools sudah berisi semua alat yang diperlukan dalam paket tingkat ataspkg_resources
.Ini bisa kurang lebih terlihat seperti ini:
sumber
pip
parsing dan bukanpkg_resources
sejak sebelum 2015 adalah bug seperti github.com/pypa/setuptools/issues/470 . Yang tepat ini sudah diperbaiki saat ini, tapi saya masih agak takut untuk menggunakannya, karena kedua implementasi tampaknya dikembangkan secara terpisah.Cross memposting jawaban saya dari pertanyaan SO ini untuk solusi bukti versi pip sederhana lainnya.
Kemudian cukup masukkan semua persyaratan Anda di
requirements.txt
bawah direktori root proyek.sumber
Saya melakukan ini:
sumber
Namun
parse_requirements
peretasan lain yang juga mem-parsing penanda lingkungan keextras_require
:Seharusnya mendukung distist sdist dan binary.
Seperti yang dinyatakan oleh orang lain,
parse_requirements
memiliki beberapa kekurangan, jadi ini bukan apa yang harus Anda lakukan pada proyek publik, tetapi mungkin cukup untuk proyek internal / pribadi.sumber
parse_requirements()
lagi, jadi ini sekarang gagal.Berikut ini adalah retasan lengkap (diuji dengan
pip 9.0.1
) berdasarkan jawaban Romain yang mem-parsingrequirements.txt
dan memfilternya sesuai dengan penanda lingkungan saat ini :sumber
r.match_markers()
Anda sebenarnya mengevaluasi marker, yang benar untuk dilakukan oleh seorang sdist. Namun, jika Anda sedang membangun dist biner (mis. Roda), paket hanya akan mencantumkan pustaka yang cocok dengan lingkungan build-time Anda.wheel environment
(jika itu yang orang coba lakukan) untuk mengevaluasi spidol yang menentangnya?bdist_wheel
. Itu tidak mengevaluasi spidol, itu hanya menambahkan merekaextras_require
.