Pip: Bawaan ke --pengguna

Dibuat pada 21 Mar 2014  ·  170Komentar  ·  Sumber: pypa/pip

Ketika pip diinstal pada sistem yang memiliki instalasi OS Python saat ini ada masalah di mana pip install foo akan memunculkan kesalahan karena tidak memiliki izin file. Ini menyebabkan orang menjalankan sudo pip install foo yang secara global diinstal ke sistem Python. Ini menciptakan masalah di mana orang menggunakan pip untuk mengelola paket tingkat sistem ketika mereka seharusnya menggunakan manajer paket sistem.

Jadi maksud saya adalah bahwa pip harus default ke --user namun ada beberapa hal yang sulit dengan ini:

  • Bagaimana ini berinteraksi dengan Windows? Apakah ini masuk akal di sana?
  • Bagaimana ini berinteraksi dengan Altinstall'd Python? Khususnya seperti yang diinstal dengan alat seperti https://github.com/yyuu/pyenv
  • Apa yang kita lakukan ketika orang memanggil pip sebagai root? Menginstal ke /root/.local/ tampaknya tidak terlalu berguna.
  • Apa artinya ini untuk get-pip dan petunjuk pemasangan pypa ?
  • ~/.local/bin tidak ada di $PATH banyak orang, apakah ada yang bisa dilakukan tentang ini?
  • --user pemasangan tidak didahulukan dari paket global easy_install 'd, yang bisa sangat tidak terduga.

Ada sejumlah masalah yang relevan di sini: #624 #1443 #1153 #1500 #1051

/cc @ncoghlan

user scheme auto-locked enhancement

Komentar yang paling membantu

Saya bermimpi di malam hari opsi --user menjadi default (tidak bercanda), apakah ada kemungkinan impian saya menjadi kenyataan dalam waktu dekat?

Semua 170 komentar

Apa artinya ini untuk instruksi pemasangan pypa?

saat ini penyebutan akses root atau Administrator ada dalam catatan kaki, jadi instruksi pada dasarnya akan tetap sama (dengan asumsi get-pip secara otomatis default ke --user juga). perubahannya adalah untuk menjelaskan bahwa mereka akan berakhir dengan pemasangan yang hanya berlaku untuk pengguna mereka saat ini.

terlepas dari perubahan --user , instruksi saat ini perlu menjelaskan bahwa beberapa distribusi seperti debian, menonaktifkan surepip, jadi mereka tidak boleh mencarinya sebagai cara untuk mendapatkan pip.

Jangka panjang saya cukup yakin mereka akan tetap mengaktifkannya, mereka hanya mencari cara untuk melakukannya.

meskipun masalah ini dijelaskan sebagai tentang di mana pip harus mengelola paket secara default, hampir lebih penting (setidaknya bagi saya) adalah bahwa ini secara tidak langsung tentang di mana get-pip akan menempatkan pip secara default.

Bagaimana ini berinteraksi dengan Altinstall'd Python?
Khususnya seperti yang diinstal dengan alat seperti https://github.com/yyuu/pyenv

skema pengguna adalah .local/lib/pythonX.Y/site-packages , jadi jika Anda mengelola banyak ular sanca dengan versi mayor/minor yang sama, saya kira Anda bisa berakhir dengan kekacauan.

untuk alat seperti itu, yang mengelola ular sanca asli, menyematkan pip ke mode global akan masuk akal untuk itu.

Masalah yang relevan pada pelacak bug redhat/fedora https://bugzilla.redhat.com/show_bug.cgi?id=662034#c10

Sepertinya Fedora/RedHat PATH=$PATH:$HOME/.local/bin:$HOME/bin sudah ada di /etc/skel/.bash_profile mereka. Ini akan membuat barang yang diinstal dengan --user masih muncul secara default, setidaknya untuk pengguna bash (shell default). Mungkin distro lain sudah punya ini?

Tidak ada yang khusus berbeda tentang Windows yang saya tahu. Tapi kami baru saja mendapatkan direktori Python standar ke PATH orang, saya tidak berharap mendapatkan direktori skrip per pengguna akan sangat mudah - dan mungkin ada kesulitan teknis juga, saya tidak yakin menempatkan variabel lingkungan tingkat pengguna seperti %LOCALAPPDATA% ke tingkat sistem %PATH% bahkan berfungsi :-(

Saya menentang terburu-buru ini. Saya lebih suka menunggu sampai kami memiliki lebih banyak pengalaman dengan pemasangan pengguna dan telah berhasil menyelesaikan masalah terlebih dahulu. Saya tahu itu masalah ayam dan telur, tapi saya tidak melihat terburu-buru untuk berubah sebagai membantu.

Juga, dengan topi Windows saya, saya harus mengatakan bahwa mempersulit pengguna Unix yang belum mengetahui bahwa penggunaan sudo yang ceroboh itu buruk untuk melakukan hal-hal bodoh, bukanlah pembenaran yang benar-benar bagus.. .

Saya berasumsi bahwa ini hanya akan berlaku ketika menjalankan pip dari sistem Python.

Nah hal yang berbeda di Windows adalah tidak ada sistem yang disediakan Python seperti yang ada di *nix yang juga dilengkapi dengan paket Python yang disediakan sistem :)

Saya juga tidak terlalu ingin terburu-buru. Saya hanya ingin memulai diskusi.

Ini tidak benar-benar memengaruhi orang yang mengetik sudo pip install karena menurut saya menginstal sesuatu sebagai root masih harus masuk ke paket situs sistem secara default. Ini akan memandu orang untuk menggunakan --user saat menjalankan sebagai pengguna yang tidak memiliki hak istimewa. Saat ini yang Anda dapatkan adalah pip install sebagai pengguna biasa baru saja melakukan kesalahan izin. Bahkan jika kami meningkatkan pesan itu untuk mengebom dan menyarankan --user itu masih bukan UX terbaik.

Dalam berbicara dengan salah satu orang Fedora, saya pikir cara yang mungkin dilakukan untuk melakukan ini adalah dengan menerapkan pemeriksaan izin. Jika saya memiliki izin untuk menulis ke direktori paket situs maka saya adalah pengguna hak istimewa dan menginstal pip ke Python global, Jika tidak maka saya adalah pengguna yang tidak memiliki hak dan menginstal ke --user .

Sejauh Windows berjalan, kami biasanya menghindari masalah karena kami menginstal Python ke direktori non-istimewa secara default, jadi pip tidak memicu UAC saat menginstal secara global. Jika seseorang mengubahnya untuk menginstal ke Program Files, maka UAC akan terpicu ketika mereka menjalankan pip (yang juga OK). Saya tidak yakin apa yang terjadi jika mereka memilih instalasi per pengguna di penginstal.

Seperti yang dicatat Paul, PATH di Windows belum menyertakan direktori skrip _user_ (hanya yang global), jadi itu pasti layak untuk diperhitungkan.

Saya tidak melihat hambatan besar di sisi POSIX. Bagaimana ide UX ini terdengar: untuk penginstalan berbasis roda, periksa izin pada direktori target penginstalan, dan jika pengguna tidak memiliki izin menulis, pasang prompt yang menanyakan apakah mereka ingin melakukan --user install sebagai gantinya? Bendera "--global" atau "--system" baru akan memaksa jawaban "tidak".

Dan kemudian di beberapa titik di masa mendatang, kita dapat melewati prompt dan hanya berasumsi --user jika izinnya tidak tepat untuk instalasi global.

Prompt (kecuali dalam kasus --no-input) mungkin masuk akal untuk langkah transisi. Saya pikir memeriksa izin harus membuat semuanya berfungsi untuk Windows juga karena secara default lokasi berada di tempat di mana orang memiliki izin dan satu-satunya waktu mereka akan menekan ini adalah jika mereka menggunakan admin sistem yang disediakan Python yang secara eksplisit tidak' t memberi mereka izin.

Pada dasarnya ini membuat mode kegagalan kami jauh lebih baik.

mempersulit pengguna Unix yang belum pernah menggunakan sudo secara sembrono
buruk untuk melakukan hal-hal bodoh, tidak benar-benar baik pembenaran..

sudo dan keamanan benar-benar merupakan masalah sekunder IMO.
ini terutama tentang mencegah konflik antara pengemasan OS dan pip dalam sistem python.
Saat ini, pengguna linux sering ditempatkan pada situasi yang tidak memungkinkan.

  1. Mandat OS: 'Gunakan OS pkg mgr; Jangan menginfeksi sistem Anda dengan paket roque pip-installed (termasuk get-pip 'd pip)'
  2. Kenyataan: "Paket OS (termasuk pip) terlalu tua, dan saya tidak dapat meningkatkan ke rilis eksperimental distro, hanya untuk mendapatkan peningkatan beberapa paket. Saya akan nakal...."

langkah kecil lainnya adalah mendokumentasikan (dengan asumsi kami mengujinya) bahwa Anda dapat get-pip.py --user , dan meminta PUG menyebutkan --user sebagai kemungkinan untuk menginstal virtualenv (dan wheel , dan twine juga, jika tidak dalam virtualenv)

FWIW, vendor distro juga menganggap status quo sebagai masalah dan mencari berbagai cara untuk meningkatkan alat untuk melakukan peningkatan selektif tanpa memengaruhi komponen inti OS. Masih layak untuk kami tangani dari sisi hulu, karena upaya tersebut berada pada berbagai tahap kedewasaan dan kami menginginkan solusi lintas platform yang konsisten untuk pengguna akhir.

Saya tidak punya masalah dengan mengubah hal-hal untuk membantu bekerja sama dengan distro di Unix; jika default ke --user pada Unix dan tidak pada Windows dapat diterima, tidak masalah bagi saya. Saya hanya tidak melihat peralihan dari pengalaman buruk di Unix ke pengalaman buruk di Windows sebagai pertukaran yang baik. Dan saya belum yakin bahwa --user di Windows siap untuk prime time.

Perhatikan bahwa memicu UAC saat menjalankan pip _is_ buruk di Windows, karena yang sebenarnya berarti pip tidak akan berjalan kecuali di jendela konsol yang ditinggikan. Itu tidak berarti bahwa pengguna pip mendapatkan prompt yang bagus yang dapat mereka katakan "OK", sayangnya, itu hanya cara kerja aplikasi GUI ...

@pfmoore Menurut Anda bagaimana seharusnya pengalaman pengguna Windows ketika Anda pip install sesuatu dan Anda tidak memiliki izin untuk menulis ke direktori?

FWIW Saya benar-benar setuju dengan menjadikan ini opsional tergantung pada Windows atau tidak. Saya hanya ingin tahu apakah pemeriksaan "Apakah saya memiliki izin untuk menulis ke folder paket situs" tidak akan mencapainya dalam 99% pemasangan, dan jika menginstal ke --user akan menjadi pengalaman yang lebih baik dalam sebagian kecil kasus di mana Anda tidak memiliki izin menulis ke direktori paket situs.

Dengan kata lain, jika kami memeriksa izin, proposal tersebut tidak menggantikan pemasangan global dengan pemasangan pengguna, itu menggantikan kesalahan izin dengan pemasangan --user .

proposal tidak menggantikan pemasangan global dengan pemasangan pengguna
itu mengganti kesalahan izin dengan --user install

ok, tapi ingat bahwa ide pemeriksaan izin (#1048) bukanlah hal yang paling mudah

Ini akan cukup mudah dalam kasus Wheel, dan kita bisa mendapatkan 99,9% kasus ditutupi dengan sdists, seharusnya hanya menjadi masalah di setup.py yang melakukan hal-hal yang sangat funky.

Menurut Anda bagaimana seharusnya pengalaman pengguna Windows ketika Anda menginstal sesuatu dan Anda tidak memiliki izin untuk menulis ke direktori?

Yah, bisa menulis ke direktori paket situs sangat jarang di Windows sehingga saya tidak yakin seberapa relevan pertanyaan itu dalam praktiknya. Tetapi jika itu terjadi, saya akan mengatakan bahwa kesalahan yang mengatakan "paket situs sistem tidak dapat ditulis - apakah Anda bermaksud menggunakan --user ?" akan menjadi pendekatan yang masuk akal.

Sebenarnya, saya pikir itu akan lebih baik di Unix juga. Mengganti perilaku tergantung pada kemampuan menulis itu aneh, dan tidak jelas bagi saya jika menggunakan --user untuk Python yang dibuat secara pribadi dalam direktori yang dapat ditulisi adalah pendekatan yang tepat (tetapi saya tidak memiliki pengalaman pengaturan seperti itu, jadi Saya tidak punya apa pun untuk mendukung pendapat itu).

Saran: Mulailah dengan kesalahan yang menyarankan --user seperti di atas. Setelah orang menggunakan --user lebih umum, dan kami memiliki lebih banyak pengalaman dengannya, mari pertimbangkan untuk mengganti default.

Pendekatan yang disarankan Paul kira-kira seperti yang ada dalam pikiran saya, tetapi dengan prompt ya/tidak daripada keluar dengan pesan kesalahan. Ada pro & kontra untuk kedua pendekatan tersebut (kebanyakan berkaitan dengan bagaimana mereka gagal ketika dipanggil dari skrip lain).

Apakah mungkin untuk menambahkan sesuatu ke Python seperti sys.localprefix (saya melihat python-dev di sini)?
Sys.localprefix akan menjadi default ke sys.prefix. Distro dapat mendefinisikannya dengan cara yang sama seperti mereka mendefinisikan prefiks (misalnya prefix = '/usr', localprefix='/usr/local'). Pip dan easy_install akan menggunakan sys.localprefix sebagai lokasi untuk menginstal jika digunakan sebagai sudo, jika mereka tidak memiliki hak yang memadai kembali ke --user.

Kami telah melakukan sesuatu seperti ini dengan "instal permata" di Fedora 17 dan pengembang Ruby umumnya sangat puas dengan hal itu, jadi saya pikir saya akan membagikan:

  • "gem install foo" menginstal "foo" ke ~/somedir jika uid != 0
  • "gem install foo" menginstal "foo" ke /usr/local/somedir jika uid == 0
  • "yum install rubygem-foo" menginstal "foo" yang dikemas dalam RPM ke /usr/somedir

Saya pikir memilih install dir berdasarkan hak pengguna akan sangat membingungkan bagi orang-orang; "pip install foo" harus bekerja dengan cara yang sama untuk semua pengguna non-root. Jika Anda mempertimbangkan sebagian besar pengguna, mereka ingin "menginstal pip" ke rumah mereka dan "sudo pip install" ke direktori seluruh sistem. Oleh karena itu saya pikir ini adalah pendekatan terbaik untuk melakukan ini berdasarkan uid seperti yang ditunjukkan di atas - dan bagi pengguna yang bukan root tetapi ingin menginstal ke direktori seluruh sistem, selalu ada opsi --target.

@bkabrda itu pilihan yang mudah untuk dibuat selama Anda tidak khawatir tentang menambahkan skrip ke $PATH. Apa yang telah Anda lakukan di sana?

@Ivoz seperti yang dicatat oleh @dstufft , Fedora sudah memiliki $HOME/.local/bin di PATH, jadi semuanya bekerja di luar kotak (berbicara tentang skrip).

Saran Slavek terdengar bagus bagi saya untuk sistem POSIX. Itu juga harus bekerja dengan baik dengan wadah, karena hal-hal yang berjalan dalam wadah dapat dikatakan berpikir itu adalah uid 0, meskipun itu adalah sesuatu yang sama sekali lain dari luar wadah.

Untuk Windows, saya kurang yakin apa jawaban yang tepat. Kami tidak memiliki masalah yang sama dengan berdebat dengan manajer paket sistem, meskipun itu memang ada sampai tingkat tertentu (instal pip vs penginstal MSI), dan memiliki komplikasi tambahan yang bahkan dalam Python 3.4, PATH opsional penginstal modifikasi hanya menambahkan direktori Skrip global, bukan direktori per pengguna.

Windows juga memiliki keanehan berdasarkan apakah Python diinstal ke lokasi default (tidak terkontrol) atau ke dalam Program Files (eskalasi hak istimewa UAC diperlukan untuk membuat perubahan).

Ide "localprefix" yang disarankan oleh @rkuska terlihat bagus bagi saya, sederhana dan mudah. Saya juga sangat menyukai pendekatan yang disarankan @bkabrda , terutama untuk distro seperti Arch yang menjadikan python 3.x sebagai python default.

Satu catatan lagi adalah, Arch telah menonaktifkan surepip di rilis 3.4.0 seperti halnya Debian (kebanyakan karena kami ingin menyediakan versi terbaru dari setuptools dan pip, sedangkan versi yang dibundel mungkin sudah ketinggalan zaman), jadi alangkah baiknya jika tip untuk itu.

@lvoz
Untuk Arch kami tidak menambahkan jalur apa pun di bawah $HOME ke PATH, tetapi saya masih menganggapnya baik-baik saja. Kami sudah memiliki entri wiki untuk Ruby yang memberitahu pengguna untuk menambahkannya.

Akan lebih baik jika daripada hanya menonaktifkannya, pengembang Arch dan Debian akan membantu Slavek mengerjakan patchnya untuk memastikanpip merekonstruksi roda dari versi sistem dan menginstalnya ke lingkungan virtual.

Sekadar informasi, kami sudah memiliki build Python 3.4 RPM yang berfungsi di sistem build Copr Fedora (pengujian, tidak disarankan untuk menginstalnya jika Anda tidak ingin merusak apa pun). Jika Anda ingin tahu lebih banyak tentang bagaimana kami mendekati ini, lihat kode dll, lihat diskusi saya dengan Barry Warsaw [2] di debian-python ML.
(Tambalan kami masih membutuhkan cinta sebelum kami mengusulkannya ke hulu, tetapi semuanya berfungsi dengan baik untuk kami ATM hilir)

[1] http://copr-fe.cloud.fedoraproject.org/coprs/bkabrda/python-3.4/
[2] https://lists.debian.org/debian-python/2014/03/msg00046.html

Maaf, tetapi AFAIK Arch tidak pernah mendukung roda, kami juga tidak ingin membuat surepip memanggil manajer paket (perbaiki saya jika saya memahami pendekatan ini salah).

Untuk surepip, itu akan menjadi ide yang bagus untuk memperingatkan pengguna untuk tidak menginstal pip menggunakan surepip, dan itulah yang paling dapat saya pikirkan untuk saat ini.

Surepip kami tidak akan pernah memanggil manajer paket. Singkatnya, surepip Fedora akan bergantung pada alat penyiapan paket sistem dan pip untuk selalu ada (paket python3 kami akan bergantung padanya, yang akan membuat loop ketergantungan, tetapi kami dapat mengatasinya) dan ketika pengguna akan membuat virtualenv baru, itu akan mengemas ulang sistem setuptools dan pip ke roda dan instal ke virtualenv baru.
Kita mulai sedikit keluar dari topik, jadi kurasa kita harus melanjutkan diskusi ini di tempat lain...

@felixonmars Apakah itu berarti di Arch venv rusak sama seperti di Debian?

Oke, terima kasih atas penjelasannya, saya pikir saya mendapat ide. Saya akan melihat apa yang bisa saya lakukan dan menindaklanjuti debian-python untuk ini.

@dstufft Ya, versi yang dibundel diinstal alih-alih versi sistem.

@bkabrda Jadi itu memecahkan masalah jika Anda menjalankan pip dengan sistem Python, kita harus kasus khusus virtualenv/venv dalam kasus itu (yang bukan akhir dunia). Tetapi itu juga berarti bahwa kita mengasumsikan semua Python adalah Python sistem, bahkan yang diinstal oleh pengguna ke homedir mereka seperti dengan https://github.com/yyuu/pyenv (begitulah cara saya menjalankan Python sebenarnya). Jadi saya tidak yakin, itu sebabnya saya memikirkan pemeriksaan izin.

sama dengan apa yang @dstufft katakan, dalam menggunakan alat seperti pyenv untuk menyulap ular sanca non-root, akan sangat aneh jika root menjadi kunci untuk melakukan instalasi global (di mana "global" != "sistem")

Kami telah melakukan sesuatu seperti ini dengan "instal permata" di Fedora 17

maksud Anda rpm permata untuk fedora 17 memiliki ini sebagai peretasan distro?, atau permata itu sendiri memiliki logika ini?

satu pemikiran adalah bahwa pip harus menyediakan "mode ramah sistem" yang dapat diaktifkan oleh distro yang mengemas pip, atau ketika pengguna tahu bahwa mereka menginstal pip sendiri ke dalam python yang dikelola sistem. jika tidak, pip melakukan logika global-by-default yang normal.

Ah @felixonmars Saya baru saja melihat https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/python , jika semua yang Anda lakukan hanyalah menelepon --without-ensurepip tidak apa-apa . Itu membuat modul surepip tetap utuh untuk modul venv. Patch yang dimiliki Ubuntu (Debian?) saat ini sebenarnya memanggil rm -rf pada paket surepip itu sendiri, membuatnya tidak tersedia untuk dipanggil dalam venv.

Saya pikir default ke pemasangan pengguna diusulkan oleh Nick dua tahun lalu, atau mungkin orang lain lebih lama, tetapi utasnya mengarah ke banyak arah dan tidak membuahkan hasil. Kendala utama adalah mundur compat IIRC, tetapi hari ini sysadmin dan pengguna pip mungkin lebih terbiasa untuk berhati-hati dengan pembaruan virtualenv/pip/setuptools, baik atau buruk. Saya tidak ingat apakah diskusi itu terjadi di distutils-sig atau pypa-dev.

@dstufft Oh, begitu... Tapi saya masih merasa salah untuk menginstal versi bundel (mungkin lama) sementara ada paket yang diinstal secara sistem :)

@felixonmars masalahnya adalah Anda tidak dapat menginstal paket sistem ke dalam virtualenv afaik :) (Dan bahkan jika Anda bisa, ada masalah yang berbeda dengan apa yang Anda inginkan dalam paket sistem vs di dalam virtualenv)

@dstufft Di situlah rewheel Slavek dimulai, tapi itu agak di luar topik :)

@dstufft Terima kasih!

Tidak yakin apakah saya harus melanjutkan diskusi di sana, karena itu seharusnya tidak menjadi masalah karena kami tidak memisahkan pip di Arch, dan rewheel harus menghasilkan roda yang dapat digunakan :)

@dstufft Anda benar bahwa kami mungkin perlu membuat kasus khusus virtualenv dan bahkan mungkin pyenv, yang tampaknya jelek. Saya harus mengakui bahwa saya tidak begitu akrab dengan pyenv, jadi saya tidak dapat memikirkan solusi "tepat" untuk itu sekarang. Saya akan mencoba untuk melihat lebih dekat dan memikirkan sesuatu.

@qwcode untuk "instal permata" di Fedora, ini adalah tambalan hilir. TBH Saya tidak menyentuh Rubygem Fedora dalam waktu lama, tetapi terakhir kali saya memeriksanya, itu hanya di bagian hilir.

Saya telah memposting tautan ke masalah ini ke bug terkait di python [1]. Saya ingin memindahkan diskusi ini ke inti python, untuk memiliki lokasi yang dapat dikonfigurasi untuk instalasi lokal tidak hanya pip tetapi juga easy_install dan python setup.py install , setelah itu pip dapat menggunakan ( misalnya) sys.localprefix dir jika uid==0 dan instal ke direktori pengguna jika uid!=0 seperti yang disebutkan @bkabrda .

Untuk saat ini saya baik-baik saja dengan menginstal pip ke direktori pengguna secara default.

[1] http://bugs.python.org/issue1298835

Seperti yang ditunjukkan Nick, saya memindahkan diskusi dari issue1298835 ke pypa-dev [1].
[1] https://groups.google.com/forum/#!topic/pypa -dev/r6qsAmJl9t0

Bawaan ke --pengguna

Ide bagus!

pip install foo akan menimbulkan kesalahan karena tidak memiliki izin file. Ini menyebabkan orang menjalankan sudo pip install foo yang secara global diinstal ke sistem Python

Ini lebih buruk dari itu. Banyak orang (seperti pengguna jaringan komputer universitas) tidak memiliki hak sudo. Ketika pip gagal dengan kesalahan izin, mereka akan:

  1. Email administrator mereka dan minta mereka untuk menginstal paket. Itu lambat dan membosankan untuk semua orang.
  2. Menyerah dan lakukan tanpa paket.

Hanya jika mereka sangat berpengalaman atau berpengetahuan luas, mereka akan mencoba pip install --user .

Jika kami akhirnya memutuskan untuk tidak menggunakan 'default ke --user', kami harus mempertimbangkan alternatif yang tidak terlalu mengganggu:

  1. Kembali ke --user (jika pemasangan gagal karena kesalahan izin)
  2. (Jika pemasangan gagal karena kesalahan izin), dorong pengguna (dalam huruf besar yang bersahabat) untuk mencoba --user

Saya sebenarnya telah menggunakan --user di semua instalasi saya untuk sementara waktu sekarang, tetapi umumnya orang tidak mengetahui opsi ini. Saya setuju itu menjengkelkan untuk melihat kesalahan izin setiap kali Anda lupa opsi. Saya perhatikan instalasi pengguna tidak kompatibel dengan conda (conda/conda#448).

Saya ingin menghidupkan kembali ini, karena orang akan menjalankannya di Windows jauh lebih sering sekarang karena 3.5 default untuk menginstal ke Program Files (yang memerlukan hak administrator untuk memodifikasi).

Saya menyukai opsi "fallback to --user on permission error" yang paling baik untuk penginstalan, dengan "default ke --user dan fallback to system" saat mencopot pemasangan dan mungkin menambahkan opsi --system atau --system-only untuk mencegah mundur. Pengguna yang dengan sengaja menjalankan pip dengan izin admin akan mendapatkan instalasi sistem seperti yang diharapkan, dan saat ini pengguna tanpa izin akan mendapatkan kesalahan, jadi saya tidak percaya ada masalah back-compat di sini.

Tujuan saya adalah agar pengguna yang tidak mengetahui informasi dapat melakukan pip install spam; python -c "import spam" tanpa kesalahan (meskipun mungkin peringatan saat mencoba kembali dengan --user ).

Saya telah memikirkan hal ini akhir-akhir ini terutama sejak #2403 dan #2401 dibuka baru-baru ini yang membuat saya berpikir tentang penggunaan sudo pip install dan bagaimana hal itu seringkali dapat merusak sistem di luar hanya masalah izin.

Untuk tujuan ini saya bertanya-tanya apakah tujuan akhir yang lebih baik bukan hanya --user adalah default, tidak ada pemeriksaan izin ajaib, dan menambahkan bendera baru seperti --global , --system , atau --no-user yang akan mengembalikan perilaku sebelumnya. Ini lebih mudah dijelaskan kepada orang-orang karena akan memiliki perilaku yang sama tidak peduli bagaimana/di mana segala sesuatunya dipasang.

Sekarang, jika kita memutuskan itu jalan yang ingin kita tempuh, masih ada masalah bagaimana kita bisa sampai ke titik itu dari tempat kita sekarang ini. Jelas pada titik mana pun kita beralih default akan menjadi perubahan yang cukup besar sehingga kita akan membutuhkan lead time yang cukup lama. Saya pikir jika kita memutuskan untuk melakukannya, cara terbaik untuk melakukannya adalah dengan terus mempertahankan opsi --user , menambahkan opsi baru seperti --global , dan kemudian jika salah satu atau opsi lain tidak dikonfigurasi, lakukan sihir pemeriksaan izin yang telah kita bicarakan dan jika sihir telah memutuskan untuk menggunakan perilaku --global , kami akan memunculkan peringatan penghentian yang sangat keras. Peringatan penghentian ini akan bertahan lebih lama daripada penghentian kami yang lain yang telah kami keluarkan karena ini akan menjadi perubahan perilaku yang cukup besar. Saya pikir kami juga ingin menambahkan opsi yang akan mematikan magic fallback dan menerapkan perilaku masa depan sehingga orang bisa mendapatkan perilaku itu hari ini.

Pertanyaan penting lainnya adalah apa yang harus kami lakukan jika kami mendeteksi bahwa Python yang kami instal tidak mengaktifkan situs pengguna. Dalam hal ini saya hanya akan menyatakan bahwa --user adalah kesalahan dan untuk Python tersebut kami hanya akan mundur ke default ke --global . Ini akan mencakup virtualenv/venv yang saya yakini secara otomatis, dan jika seseorang menginginkan lingkungan yang terisolasi dengan bobot "lebih berat" menggunakan Python yang dikompilasi sepenuhnya, mereka dapat dengan mudah menambal site.py sehingga mereka menetapkan ENABLE_USER_SITE ke False di bagian atas file.

+1, dan saya akan memilih --system.

Saya akan perhatikan, dan saya yakin Anda akan menyukai ini, default Ubuntu telah berubah:

https://launchpad.net/ubuntu/+source/python-pip/1.5.6-4ubuntu1

Pada 09 Februari 2015, pukul 16:41, Donald Stufft menulis:

Untuk tujuan ini saya bertanya-tanya apakah tujuan akhir yang lebih baik bukan hanya --user adalah
default, tidak ada pemeriksaan izin ajaib, dan tambahkan tanda baru seperti --global ,
--system , atau --no-user yang akan mengembalikan perilaku sebelumnya. Ini
lebih mudah untuk menjelaskan kepada orang-orang karena itu akan memiliki perilaku yang sama tidak peduli
bagaimana/di mana sesuatu dipasang.

Saya pikir --system salah karena itu benar-benar hanya berlaku untuk beberapa Python. Ini tidak berlaku untuk:

  • Python di Windows
  • pyenv menginstal Python
  • Conda menginstal Python
  • Nix Terpasang Python
  • Python yang Dikompilasi Khusus.

Ini _only_ berlaku pada sistem *nix di mana Python kebetulan dikirimkan oleh sistem. Saya merasa --global adalah nama yang jauh lebih baik untuk bendera itu.

Dan FML, mengapa Debian/Ubuntu merasa perlu untuk terus-menerus menambahkan tambalan acak yang merusak kasus penggunaan yang diharapkan?

Jadi jika tambalan Ubuntu dikembalikan, apa timeline untuk memperbaikinya di sini? Seminggu/sebulan/3 bulan/6 bulan/tahun...?

Itu tergantung pada apa yang Anda maksud dengan tetap.

Dengan asumsi sejenak kami menggunakan ide yang saya miliki 2 posting yang lalu (yang masih perlu ditandatangani dari pengembang pip lainnya), kami mungkin dapat dengan cepat mendapatkan rencana transisi di mana yang berikut ini berlaku:

  • Ketika --user dilewatkan, kami _selalu_ menginstal ke dalam paket situs pengguna.
  • Ketika --global (atau apa pun) diteruskan, kami _selalu_ menginstal ke dalam paket situs global.
  • Ketika tidak ada yang dilewati, kami menerapkan metode fallback yang:

    • Mendeteksi jika kita berada di lingkungan virtual dan jika demikian bertindak seolah-olah --global dilewatkan.

    • Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah --global diteruskan.

    • Mendeteksi jika pengguna yang efektif tidak memiliki izin menulis ke sys.path , dan jika mereka tidak bertindak seolah-olah --user diteruskan.

    • Terakhir, jika semua metode deteksi lainnya gagal, bertindaklah seolah-olah --global telah diteruskan dan cetak peringatan penghentian yang mengatakan bahwa di beberapa titik di masa mendatang, perilaku ini akan berubah dan sebagai gantinya akan dipasang ke --user .

Ini tidak akan menghentikan seseorang dari melakukan sudo pip install foo ke dalam sistem Python mereka, namun itu akan mencetak peringatan bahwa pada titik tertentu ini akan berarti --user dan memberitahu mereka untuk secara eksplisit mulai menggunakan --global . Setelah hal di atas dirilis untuk waktu yang cukup lama, kami kemudian dapat menghapus jalur kode yang tidak digunakan lagi dan menyederhanakannya sehingga menjadi sederhana:

  • Ketika --user dilewatkan, kami _selalu_ menginstal ke dalam paket situs pengguna.
  • Ketika --global (atau apa pun) diteruskan, kami _selalu_ menginstal ke dalam paket situs global.
  • Ketika tidak ada opsi yang diteruskan, kami menerapkan metode fallback yang:

    • Mendeteksi jika kita berada di lingkungan virtual dan jika demikian bertindak seolah-olah --global dilewatkan.

    • Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah --global diteruskan.

    • Akhirnya menggunakan --user sebagai default.

Namun, perpindahan dari perilaku pertama ke perilaku kedua akan memiliki garis waktu yang cukup panjang. Itu akan menjadi perubahan yang sangat besar yang akan merusak banyak hal untuk perangkat lunak apa pun (seperti garam, koki, boneka) atau skrip penerapan (seperti skrip Fabric yang dibuat khusus untuk ribuan proyek di seluruh dunia) yang mengharapkan itu sudo pip install <foo> akan diinstal ke Python global. Kita perlu memberikan waktu yang lama bagi orang-orang untuk melihat peringatan tersebut, dan memodifikasi perangkat lunak dan skrip mereka untuk meneruskan tanda --global eksplisit jika mereka benar-benar membutuhkan perilaku itu.

Saya pikir rencana yang disarankan Donald adalah rencana yang bagus, meskipun jika tim pip memutuskan untuk mengadopsi pendekatan itu, kami juga harus mengajukan masalah pemblokir rilis 3,5 dengan CPython untuk mendapatkan direktori skrip per pengguna ditambahkan ke jalur di Windows bersama dengan global satu. Jika 3.5 menambahkan itu bersama dengan peralihan untuk menginstal ke Program Files secara default, maka kita harus mendapatkan perilaku menginstal yang diinginkan tanpa izin admin terus "hanya bekerja".

Mampu mengubah lokasi pemasangan default melalui file konfigurasi pip mungkin juga berguna, memungkinkan orang untuk memilih "per-pengguna secara default" pada sistem mereka sendiri, bahkan jika defaultnya belum berubah. (mis. "default-install=user" vs "default-install=global")

@dstufft : Saya senang membantu mengimplementasikan proposal Anda seperti yang diceritakan pada bug ubuntu jika Anda membutuhkan saya. Setelah kami mendapatkan perilaku itu di bagasi, saya akan mem-backport dan mengganti tambalan ubuntu saat ini dengan ini tentu saja.

Beritahu saya jika Anda membutuhkan bantuan.

Saya memberi +1 pada paket @dstufft . Saya akan memilih --global sebagai namanya, untuk alasan yang disebutkan. Kami sudah duduk di pagar cukup lama sekarang, mari kita lakukan.

O'n dan +1 pada saran @ncoghlan agar Python 3.5 menambahkan direktori situs pengguna ke PATH di Windows. Mari kita hindari batu sandungan lebih lanjut untuk transisi ini.

Saya juga memberi +1 untuk paket @dstufft dan +1 untuk --global , meskipun saya masih bertanya-tanya tentang sudo pip install foo yang membutuhkan --global . Apakah sebenarnya ada kebutuhan root untuk memiliki paket situs pengguna? Bisakah kita melakukan root kasus khusus untuk menonaktifkan paket situs secara default? (Yang akan membuat sudo pip install foo berfungsi seperti sekarang)

Saya belum pernah melihat orang menggunakan --user untuk root dengan status saat ini, tetapi jika seseorang benar-benar mengetahui kasus penggunaan seperti itu, saya ingin tahu.

Satu pemikiran yang terpikir oleh saya adalah bagaimana direktori situs pengguna akan bekerja dengan beberapa versi Python yang diinstal?

Jika saya melakukan pip install pytest --user di Python 2.7 dan 3.4 (dengan Python 3.4 Python default saya), versi mana yang akan dijalankan oleh perintah py.test ? Saya memiliki kecurigaan bahwa kedua pemasangan akan saling menimpa sehingga ini adalah situasi "yang terakhir menang", yang _tidak_ bagus. Juga, jika "yang terakhir menang", dan saya menginstal versi 2.7 setelah versi 3.4, bagaimana cara memperbaikinya untuk menjadikan 3.4 sebagai default lagi?

Dan bagaimana dengan uninstall? Pertimbangkan skenario berikut (belum diuji, karena saya perlu menyiapkan mesin bersih jika saya tidak ingin mengambil risiko merusak laptop utama saya):

    C:\Apps\Python34\python.exe -m pip install pytest --user
    C:\Apps\Python27\python.exe -m pip install pytest --user
    C:\Apps\Python34\python.exe -m pip uninstall -y pytest

Pertama, mengapa perintah kedua tidak mengeluarkan peringatan bahwa itu menimpa file yang ada? Atau akankah? Apakah berhasil atau tidak, apakah saya punya pilihan tentang apa yang harus dilakukan?

Kedua, apakah uninstall tidak gagal karena checksum py.test.exe tidak cocok dengan nilai dalam file RECORD ? Jika gagal, bagaimana cara menghapus instalannya? Jika tidak gagal, apakah itu akan merusak salinan pytest Python 2.7 saya (dengan menghapus exe)?

Dan akhirnya (untuk saat ini!) akankah direktori skrip pengguna pergi sebelum atau sesudah direktori skrip sistem di PATH? IMO, itu harus diikuti, karena jika tidak, pengguna menginstal paket dalam Python yang _not_ diminta oleh pengguna untuk menjadi "Python default" dapat menimpa paket yang sama yang diinstal di paket situs sistem "default" Python.

Hmm, mungkin ada beberapa pertanyaan terbuka yang perlu diselesaikan sebelum kita melakukan perubahan ini...

Saya berharap bentrokan nama di direktori skrip pengguna Windows bersama ditangani dengan cara yang sama seperti yang ditangani pada sistem POSIX dengan direktori bin bersama mereka: Python 3 tidak akan menginstal nama skrip yang tidak memenuhi syarat untuk paket yang diinstal, jadi yang tidak memenuhi syarat name akan merujuk ke versi Python 2.

Hal yang sama berlaku untuk apakah pemasangan sistem atau pemasangan per pengguna didahulukan secara default: letakkan direktori skrip pengguna setelah direktori sistem.

"Python 3 tidak akan menginstal nama skrip yang tidak memenuhi syarat untuk paket yang diinstal" - mungkin maksud Anda bahwa pip dan setuptools (di bawah Python 3) tidak akan, di sini? Jadi itu perubahan alat-alat itu?

Oh, dan bleh. Memori otot saya 100% terlatih untuk mengetik "pip install foo" untuk menginstal ke Python default saya (3.4). Itu akan menjadi neraka untuk melatih kembali.

Juga, pengguna Windows dapat memilih apakah "python" berarti Python 2 atau 3 (melalui "jadikan ini sebagai Python default" dan "Tambahkan ke PATH") - tidak seperti pengguna Unix di mana sistem Python membuat aturan. Jadi jika saya mengatakan saya ingin menjadikan Python 3.5 default saya, mengapa "pip" (atau nama lain yang tidak memenuhi syarat) tidak boleh merujuk ke versi itu? Tampaknya aneh bahwa pengguna dengan hanya Python 3.5 yang diinstal pada Windows tidak dapat menggunakan nama yang tidak memenuhi syarat hanya karena masalah Unix seputar bagaimana sistem Python membutuhkan sesuatu yang dinamai. (Maaf jika deskripsi saya tentang batasan Unix tidak akurat - saya tidak begitu mengerti masalah di sana). Orang yang menginstal beberapa versi Python memerlukan solusi, tetapi solusi itu seharusnya tidak memengaruhi mayoritas yang hanya membutuhkan satu versi.

Mungkin jawaban paling sederhana adalah bahwa direktori skrip pengguna harus diversi, sama seperti direktori paket situs pengguna?

Oh, dan haruskah debat ini menggunakan python-dev daripada di sini, karena ini lebih umum tentang direktori situs pengguna?

Membuka kembali diskusi desain PEP 370 untuk direktori skrip per pengguna Windows di python-dev tentu saja masuk akal. Aneh bahwa instalasi skrip global pada Windows dicakup oleh versi Python, tetapi instalasi skrip per pengguna tidak.

Itu kontras dengan situasi di POSIX, yang secara konsisten menggunakan namespace bersama untuk executable di kedua level (global atau per pengguna), jadi konflik nama lebih mungkin muncul pada waktu instalasi, daripada melalui bayangan nama saat runtime.

Sejauh solusi umum untuk menangani instalasi paralel, itu adalah sakelar "-m" - dengan begitu Anda selalu tahu Python mana yang Anda gunakan, daripada menebak tentang isi dari baris shebang skrip terpisah.

Dipahami kembali -m , tetapi terakhir kali diangkat dalam konteks bagaimana mendokumentasikan sesuatu, preferensi yang kuat adalah bahwa kita harus memperlakukan pip install foo sebagai cara kanonik untuk menginstal sesuatu (dengan -m dan perintah berversi diperlakukan sebagai pengecualian untuk kasus khusus.

Manual pip bahkan tidak _menyebutkan_ alternatif (kecuali dalam satu kasus menggunakan -m untuk memutakhirkan pip itu sendiri di Windows).

Saya merekomendasikan -m dalam dokumen paket stdlib untuk menangani pemanggilan pip ketika
berurusan dengan instalasi Python paralel - itu satu-satunya gaya doa yang
bekerja di semua platform, untuk pemasangan global, pemasangan pengguna, dan virtual
lingkungan.

Pada 09 Februari 2015, pukul 19:58, ncoghlan menulis:

Mampu mengubah lokasi pemasangan default melalui file konfigurasi pip
mungkin juga berguna, memungkinkan orang untuk memilih "per-pengguna secara default" di
sistem mereka sendiri, bahkan jika defaultnya tidak berubah
belum. (mis. "default-install=user" vs "default-install=global")

Saya suka ini. Salah satu hal yang kita perjuangkan adalah bagaimana menyelesaikannya
pendekatan hulu yang lebih konservatif untuk bermigrasi ke --user default, dengan
distro bersaing untuk membuat sistem pip aman dan konsisten dengan yang lain
peralatan. Misalnya

https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1419695
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=725848

Jika kami memiliki file konfigurasi seluruh sistem untuk memilih default, maka di
setidaknya semua mesin yang terlibat akan identik, dan distro tidak akan
harus membawa delta jelek. Yang harus kita lakukan hanyalah mengubah
config file dan dokumen itu kepada pengguna kami. Masalah yang ditimbulkan adalah
kita untuk menangani, tapi setidaknya akan mudah untuk menjelaskan.

Saya tidak berpikir Debuntu saat ini menginstal file pip.conf seluruh situs (saya akan memiliki
untuk memeriksa ulang).

https://pip.pypa.io/en/latest/user_guide.html#configuration

Satu komplikasi: kami memasang skrip pip yang berbeda untuk Python 2 dan Python 3,
jadi saya pikir kita memerlukan file konfigurasi terpisah untuk versi yang berbeda dari
Python, misalnya /etc/{xdg/pip/}/pip{2,3}.conf atau semacamnya.

Pada 10 Februari 2015, pukul 01:24, Paul Moore menulis:

Satu pemikiran yang terpikir oleh saya adalah bagaimana direktori situs pengguna bekerja dengan
beberapa versi Python diinstal?

Di Debian/Ubuntu (mungkin semua *nix?) Kami tidak memiliki tabrakan karena
perpustakaan diinstal ke ~/.local/lib/pythonX.Y/site-packages

Kami _do_ mendapatkan tabrakan pada ~/.local/bin sekalipun. Menginstal paket dengan a
skrip 'foo' menggunakan pip install --user foo dan pip3 install --user foo akan
akhirnya menghancurkan skrip ~/.local/bin/foo.

Satu kelemahan dari perubahan ini adalah menurut saya Fedora adalah satu-satunya distro hilir yang menambahkan ~/.local/bin ke $PATH secara default (dan itu harus muncul sebelum /usr/bin dan /usr/local/bin hanya seperti paket situs pengguna datang sebelum paket situs). Idealnya downstream dapat memodifikasi sistem mereka sehingga ~/.local/bin berada di $PATH secara default.

Pada 10 Februari 2015, pukul 07:24, Donald Stufft menulis:

Satu kelemahan dari perubahan ini adalah saya pikir Fedora adalah satu-satunya hilir
distro yang menambahkan ~/.local/bin ke $PATH secara default (dan seharusnya datang
sebelum /usr/bin dan /usr/local/bin seperti halnya paket situs pengguna datang
sebelum paket situs). Idealnya hilir akan dapat memodifikasi
sistem sehingga ~/.local/bin pada $PATH secara default.

Ya, tapi kita bisa membuat keputusan terpisah tentang itu. (Atau lebih tepatnya, hilir
distro dapat melakukan itu.)

(dan itu harus muncul sebelum /usr/bin dan /usr/local/bin seperti pengguna
paket situs datang sebelum paket situs)

Hmm, @ncoghlan justru mengatakan sebaliknya, bahwa (di Windows, khususnya
konteks) direktori skrip pengguna harus _setelah_ sistem. Yang
Saya setuju selama direktori skrip pengguna tidak berversi. Jika itu
versi, saya kurang peduli. Tapi itu mungkin mencerminkan fakta bahwa
Pengguna Windows tidak pernah perlu menanggung bentrokan skrip yang tidak berversi dan
monster seperti pip2/pip3, cara yang dimiliki pengguna Unix ;-)

Oh, dan masalah skrip yang gagal adalah masalah yang lebih umum yang sebenarnya tidak terkait dengan --user secara persis. Masalah yang sama ada di mana-mana kecuali Windows --global menginstal. Saya pikir solusi untuk masalah itu adalah masalah/masalah sekunder yang harus kita selesaikan secara terpisah untuk masalah ini.

Jadi pemikiran saat ini:

  • Saya pikir ada kesepakatan tentang ide umum yang saya posting sebelumnya, jadi saya pikir kami ingin bergerak maju dengan sesuatu seperti itu.
  • Kita akan menggunakan flag --global .
  • Kami mungkin menginginkan semacam peringatan jika kami menginstal ke --user dan ~/.local/bin tidak ada di $PATH .
  • Kami akan menginginkan semacam opsi default-install yang pada dasarnya akan menonaktifkan perilaku fallback dan hanya melakukan hardcode ke --global atau --user .
  • Pada pip 6.0 kami memiliki file konfigurasi khusus mesin yang terletak di /etc/ namun ini tidak spesifik untuk versi Python yang menjalankan pip. Saya pikir itu fitur yang bagus meskipun agak terpisah juga (dan mungkin berjalan seiring dengan memecahkan masalah skrip juga).

Saya masih melihat satu pertanyaan besar yang masih terbuka: Jangka panjang apa yang kita inginkan terjadi ketika seseorang melakukan sudo pip install foo atau lebih tepatnya, jika seseorang memiliki izin untuk menulis ke direktori site-packages ?

Opsi yang dapat saya pikirkan adalah:

  1. Instal ke --global . Ini adalah opsi yang paling kompatibel dan kemungkinan mewakili apa yang diharapkan pengguna saat mereka mengetiknya. Namun ia memiliki kelemahan yang akan (diam-diam) mengacaukan Python global, yang pada banyak sistem dapat menyebabkan sistem rusak.
  2. Instal ke --user , ini akan melindungi dari sistem yang rusak (saya pikir?) tetapi saya tidak berpikir ada orang yang mengharapkan pengguna root untuk mendapatkan instalasi /root/.local/ .
  3. Hanya kesalahan dan meminta pengguna untuk memilih --user atau --global secara manual.
  4. Pilih salah satu dari dua opsi pertama, tetapi berikan sakelar yang dapat diaktifkan distro di /etc/ yang akan mengaktifkan opsi ketiga.

Opsi keempat mungkin yang terbaik tetapi saya merasa kita harus mencoba memilih salah satu opsi lain terlebih dahulu jika kita dapat menemukan semacam solusi yang bekerja sama di semua platform/skenario dan masuk akal pada semuanya seperti yang saya lebih suka memiliki perilaku lintas platform yang konsisten jika memungkinkan.

Saya merasa opsi ketiga kemungkinan buruk, karena "Saya memiliki izin menulis" akan menjadi skenario bahwa siapa pun di Windows menggunakan pra Python 3.5, atau siapa pun yang menggunakan Conda, atau siapa pun yang menggunakan pyenv. Kesalahan keluar sepertinya hal yang salah untuk dilakukan dalam semua kasus itu dan agak tidak ramah pengguna untuk boot.

Jadi saya kira antara 1 dan 2 itu benar-benar bermuara pada seberapa buruk praktik yang menurut kami dilakukan orang (secara konseptual) sudo pip install --global foo . Di Windows, Conda, pyenv, dll. Saya merasa jawabannya adalah "kami tidak berpikir itu praktik yang buruk sama sekali". Pada * nix saya merasa mungkin jawabannya adalah "pengguna harus diizinkan untuk melakukan apa yang mereka inginkan ke sistem mereka tetapi kami harus menyediakan rel untuk membawa mereka menjauh dari hal-hal "buruk"".

Jadi memikirkannya lebih jauh, saya pikir saya harus memilih opsi pertama sebagai opsi yang tepat untuk kita ikuti. Itu menyelesaikan masalah kompatibilitas mundur kurang lebih karena perilaku yang benar-benar akan kami ubah adalah jika Anda mengetik pip install foo tanpa izin untuk menginstal ke direktori global itu, Anda akan menginstal ke --user alih-alih meningkatkan kesalahan. Saya pikir tidak mungkin ada orang di luar sana yang benar-benar bergantung pada pip yang meningkatkan kesalahan dalam kasus itu. Saya juga berpikir bahwa pip install --user sebagai pengguna root tidak mungkin seperti yang diharapkan atau diinginkan siapa pun dan itu benar-benar hanya membuat pijakan bagi pengguna.

Jadi proposal saya yang diperbarui adalah:

  • Ketika --user dilewatkan, kami selalu menginstal ke dalam paket situs pengguna.
  • Ketika --global dilewatkan, kami selalu menginstal ke dalam paket situs global.
  • Ketika tidak ada yang dilewati, kami menerapkan metode fallback yang:

    1. Mendeteksi jika kita berada di lingkungan virtual dan jika demikian bertindak seolah-olah --global dilewatkan.

    2. Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah --global diteruskan.

    3. Melihat default-install dan jika itu ada gunakan --user atau -global berdasarkan itu.

    4. Mendeteksi jika pengguna efektif tidak memiliki izin menulis ke paket situs global, dan jika mereka tidak bertindak seolah-olah --user diteruskan.

    5. Terakhir, jika semua metode deteksi lainnya gagal, bertindaklah seolah-olah --global telah dilewati.

Ini berarti tidak ada periode penghentian dan harapannya adalah bahwa dengan tidak adanya --user atau --global kami akan mencoba membuat tebakan terbaik berdasarkan kemampuan Python yang kami jalankan , pengguna efektif, dan metode pemasangan default yang dikonfigurasi.

(dan itu harus muncul sebelum /usr/bin dan /usr/local/bin seperti pengguna
paket situs datang sebelum paket situs)

Hmm, @ncoghlan justru mengatakan sebaliknya, bahwa (di Windows, khususnya
konteks) direktori skrip pengguna harus _setelah_ sistem. Yang
Saya setuju selama direktori skrip pengguna tidak berversi. Jika itu
versi, saya kurang peduli. Tapi itu mungkin mencerminkan fakta bahwa
Pengguna Windows tidak pernah perlu menanggung bentrokan skrip yang tidak berversi dan
monster seperti pip2/pip3, cara yang dimiliki pengguna Unix ;-)

Saya bahkan tidak berpikir dalam hal nama skrip yang bentrok. Saya hanya berpikir bahwa variabel $PATH kita bertindak berbeda dari sys.path . Sejauh yang saya tahu pemesanan sys.path adalah: stdlib > paket situs pengguna > paket situs global. Saya pikir akan sangat membingungkan jika pemesanan some-script adalah global bin dir > user bin dir sedangkan python -m some-script adalah paket situs pengguna > paket situs global.

Jika ada masalah dengan direktori skrip (dan berversi vs tidak berversi) maka saya pikir kita harus memperbaiki masalah itu tetapi itu tidak terlalu relevan dengan urutan yang seharusnya, karena saya merasa seperti apa pun selain mencocokkan apa sys.path tidak sangat salah.

Poin bagus, kita harus berasumsi (dan merekomendasikan) bahwa $PATH mengikuti sys.path, dengan (dalam istilah Windows) C:PythonXY sebelum %APPDATA%PythonXYScripts sebelum C:PythonXYScripts. Saya akan mencatat itu di utas python-dev.

Proposal terbaru Donald terdengar bagus bagi saya (sama dengan proposal asli saya ditambah semua detail penting yang saya tinggalkan :)). Saya setuju 100% dengan paragraf "Jadi pikirkan lagi..." juga.

Untuk mengonfigurasi PATH di Windows, itu hampir tidak mungkin. Penginstal seluruh sistem hanya dapat mengonfigurasi variabel lingkungan di seluruh sistem dan tidak dapat menyertakan perluasan, jadi Anda tidak dapat menetapkan jalur yang berbeda untuk setiap pengguna. (Pemasang per pengguna dapat melakukannya, tetapi dalam hal ini --global akan berhasil sehingga tidak perlu.)

Juga, karena penanganan PATH Windows yang rusak, pengaturan seluruh sistem _always_ mengalahkan pengaturan per pengguna. Ini mengarah ke setengah saran saya beberapa waktu lalu (di python-dev, IIRC) tentang menggunakan peluncur py.exe untuk skrip yang tidak berversi, sehingga pip.exe akan selalu pergi ke sistem atau pengguna Python terbaru daripada yang menginstalnya, dan (misalnya) pip.exe -3.5 akan memungkinkan pemilihan versi tertentu.

Satu-satunya cara untuk membuat ini benar-benar berfungsi adalah agar penginstal Python mulai menginstal file batch untuk mengonfigurasi PATH berdasarkan permintaan (dan mungkin pintasan yang menjalankan file batch). Jadi hal pertama yang akan diketik pengguna adalah activate-py35 dan kemudian PATH mereka dikonfigurasi dengan benar untuk 3.5. Saya sangat bingung dengan ini, karena saya tidak ingin masuk ke situasi vcvarsall.bat, tetapi pada saat yang sama itu akan bagus untuk skrip yang saat ini membuat asumsi tentang lokasi pemasangan atau mencoba dan menelusuri registri untuk menemukannya.

dan mungkin pintasan yang menjalankan file batch

Dalam pikiran saya, ini adalah pintasan Command Prompt "Python 3.5 (32-bit)". Pengguna Visual Studio harus mengenali paralelnya.

Saya tidak cukup tahu tentang Windows untuk memahami sepenuhnya implikasi dari semua itu, tetapi saya merasa sangat buruk tentang kembali ke situasi di mana pip install foo yang menginstal skrip foo tidak dapat segera dieksekusi sebagai foo pada baris perintah. Jika kita menginstal ke --user dan itu tidak berada di jalurnya secara default, maka itu terasa seperti regresi yang cukup besar bagi saya.

Saya tidak yakin saya mengerti persis bagaimana menggunakan py.exe untuk skrip yang tidak berversi akan bekerja dalam praktik dan apakah itu benar-benar akan menyelesaikan masalah atau tidak. Saya secara pribadi tidak terikat untuk membuat skrip persis seperti kita hari ini, jadi jika itu _berfungsi, saya pikir kita mungkin bisa melakukannya, tetapi saya harus lebih memahami implikasinya sebelum saya dapat memberikan +1 saya padanya.

Untuk mengonfigurasi PATH di Windows, itu hampir tidak mungkin. Penginstal seluruh sistem hanya dapat mengonfigurasi variabel lingkungan di seluruh sistem dan tidak dapat menyertakan perluasan, jadi Anda tidak dapat menetapkan jalur yang berbeda untuk setiap pengguna.

Oh, yuk. Aku lupa itu.

dan mungkin pintasan yang menjalankan file batch
Dalam pikiran saya, ini adalah pintasan Command Prompt "Python 3.5 (32-bit)". Pengguna Visual Studio harus mengenali paralelnya.

... yang mengerikan bagi kita yang default ke Powershell untuk semuanya.

tetapi saya merasa sangat buruk tentang kembali ke situasi di mana pip install foo yang menginstal skrip foo tidak dapat segera dieksekusi sebagai foo pada baris perintah.

Sepakat. Ini akan menjadi kemunduran yang buruk, dan perlu ditangani. Saya hanya berharap seseorang bisa memikirkan cara :-)

Saya tidak yakin saya mengerti persis bagaimana menggunakan py.exe untuk skrip yang tidak berversi akan bekerja dalam praktik

Saya pikir intinya (yang hanya sedikit terkait dengan py.exe ) adalah bahwa pembungkus exe, daripada menggunakan juru bahasa Python yang dikodekan dengan keras seperti saat ini, harus secara dinamis memilih juru bahasa berdasarkan "apa adalah default" entah bagaimana (registry, file py.exe ini, apa pun yang diberikan Python %PATH% kepada Anda, ...). Saya tidak yakin bagaimana itu akan membantu, karena kami masih memerlukan direktori skrip pengguna berversi (untuk menghindari file saling menimpa atau file dijalankan dengan penerjemah yang tidak menginstal paket) dan kami masih akan melakukannya 'tidak dapat menempatkan itu pada titik yang tepat di %PATH%.

... yang mengerikan bagi kita yang default ke Powershell untuk semuanya.

Saya baru saja mencobanya, dan saya dapat dengan mudah membuat file activate-py35.bat dan activate-py35.ps1 yang terlihat dan berperilaku identik (yaitu, semua orang hanya perlu menulis activate-py35 dan memperbarui jalurnya). Masih tidak ideal, tapi mungkin yang terbaik dari situasi yang buruk.

Saya tidak yakin saya mengerti persis bagaimana menggunakan py.exe untuk skrip yang tidak berversi akan bekerja dalam praktik

Saya pikir intinya (yang hanya agak terkait dengan py.exe ) adalah bahwa pembungkus exe, daripada menggunakan juru bahasa Python yang dikodekan dengan keras seperti saat ini, harus secara dinamis memilih juru bahasa berdasarkan "apa adalah default" entah bagaimana

"Entah bagaimana" adalah tempat py.exe masuk - aturan yang sama harus digunakan. Jika peluncur diperbarui untuk memeriksa namanya sendiri, maka alih-alih meluncurkan python.exe ia dapat mencoba dan meluncurkan 'scripts\\{}{}.{}.exe'.format(argv[0], major_version, minor_version) (dengan pemangkasan ekstensi yang sesuai pada argv[0] , dll.) sebagai gantinya. Kemudian penginstal perlu menggunakan file yang berbeda untuk peluncur tidak berversi dari yang berversi lengkap (yang tidak akan berubah mulai hari ini), tetapi file itu hanya akan menjadi py.exe normal dengan nama baru. (Ini bisa menjadi lebih sederhana di masa lalu dari file pip-script.py , tetapi sekarang setelah file itu hilang ...)

Tapi seperti yang Anda katakan, PATH masih menjadi masalah. Saya tidak punya solusi bagus, dan bahkan tidak banyak solusi buruk. Variabel lingkungan benar-benar dimaksudkan untuk dikonfigurasi oleh administrator atau pengguna, bukan penginstal.

Kami dapat menyesuaikan cara kami menginstal skrip untuk membuat pengalaman pengguna yang lebih baik. Semuanya seimbang, gabungan file .exe dan .py membuat segalanya lebih baik bagi pengguna karena hanya ada file .exe tunggal. Namun saya merasa mendapatkan cerita terbaik untuk pip install foo && foo lebih penting daripada hal itu, jadi jika kita perlu memisahkan .exe dan .py lagi, saya pikir itu a tradeoff yang bagus untuk jawaban yang bagus.

Pemisahan .exe / .py adalah masalah yang paling kecil :)

Saya sebenarnya sedang melakukan pemanasan (atau dengan enggan menerima?) ide activate-py35 . Saya tidak pernah menjadi penggemar installer yang menambahkan Python ke PATH sama sekali, dan perintah py -m pip belum benar-benar mendapatkan daya tarik (dan juga tidak akan berfungsi untuk, katakanlah, Sphinx). Saya akan menulis deskripsi yang lebih rinci tentang bagaimana activate-py dapat bekerja dan mempostingnya ke python-dev untuk melihat apakah itu mendapat daya tarik.

Apakah file activate-whatever ini akan serupa dengan yang ada di dalam lingkungan virtual? Kecuali alih-alih lingkungan virtual ditambahkan ke $PATH itu menambahkan Python asli?

Ya, hampir identik. Di python-dev saya baru saja menyarankan agar mereka mengambil parameter -x.y , meneruskannya ke py.exe dan menggunakan sysconfig untuk mendapatkan jalur.

Oke. Saya tidak memiliki pendapat tentang seberapa buruk itu bagi pengguna Windows karena saya bukan salah satunya. Kedengarannya tidak benar-benar mengerikan (mungkin?) Tapi itu sejauh pengetahuan Windows saya dapat membawa saya.

Pada 10 Februari 2015, pukul 08:02, Donald Stufft menulis:

Oh, dan masalah skrip yang gagal adalah masalah yang lebih umum yang bukan
benar-benar terkait dengan --user persis. Masalah yang sama ada di mana-mana
kecuali Windows --global menginstal. Saya pikir solusi untuk masalah itu adalah
kekhawatiran/masalah sekunder yang harus kita selesaikan secara terpisah untuk masalah ini.

Sepakat.

Kita akan menggunakan flag --global .

+1

Kami mungkin menginginkan semacam peringatan jika kami menginstal ke --user dan
~/.local/bin tidak ada di $PATH .

+1, mungkin dengan opsi konfigurasi untuk menekan peringatan?

Kami akan menginginkan semacam opsi default-install yang pada dasarnya akan
nonaktifkan perilaku mundur dan cukup hardcode ke --global atau
--user .

+1

Pada pip 6.0 kami memiliki file konfigurasi khusus mesin yang terletak di /etc/
namun ini tidak spesifik untuk versi Python yang dijalankan
pip. Saya pikir itu fitur yang bagus meskipun agak terpisah juga (dan
mungkin berjalan seiring dengan memecahkan masalah skrip juga).

Saya akan menyarankan urutan pencarian seperti:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

di-root dulu(?) di /etc/xdg/pip lalu /etc, di mana XY tentu saja adalah
nomor versi mayor.minor. Yang pertama ditemukan, menang.

Saya melihat satu pertanyaan besar yang masih terbuka: Jangka panjang apa yang kita inginkan terjadi ketika
seseorang melakukan sudo pip install foo atau lebih tepatnya, jika seseorang memiliki izin untuk
menulis ke direktori site-packages ?

Harap dicatat bahwa tidak hanya ada satu direktori "paket situs". Sebagai contoh,
di Debian/Ubuntu kami tidak ingin sudo pip install _ever_ menginstal ke
/usr/lib, tetapi hanya /usr/local/lib. Dan jangan lupa, ini adalah paket-paket di sini
bukan paket situs (kecuali di ~/.local karena $reasons).

Ini benar-benar poin penting yang terkadang dilupakan (bahkan oleh saya).
Donald menggambarkannya dengan baik ketika dia mengatakan ada direktori situs-lokal dan a
direktori vendor-lokal. Di Debian, situs-lokal adalah
/usr/lib/pythonX.Y/dist-packages dan tidak ada perintah pip yang boleh menyentuhnya,
sementara vendor-local adalah /usr/local/lib/pythonX.Y/dist-packages dan itu adalah
kasus penggunaan yang didokumentasikan dan populer untuk beberapa administrator sistem untuk menginstal pip
ke dalam direktori itu.

Jadi yang saya sarankan, karena kita sudah menelusuri jalur file konfigurasi, adalah untuk
buat ini dapat dikonfigurasi, mis

  • global_install_directory
  • global_install_as_sudo (benar/salah)
  1. Instal ke --global . Ini adalah opsi yang paling kompatibel dengan versi sebelumnya
    dan kemungkinan mewakili apa yang diharapkan pengguna saat mereka mengetiknya. Namun memiliki
    kelemahannya adalah (diam-diam) mengacaukan Python global, yang pada banyak
    sistem dapat menyebabkan sistem rusak.

Dengan konfigurasi di atas, ini akan sepenuhnya kompatibel dengan Debian.
Pengguna super Debian mengharapkan sudo pip install untuk masuk
/usr/local/lib/pythonX.Y/dist-packages. Saya tidak akan mengatakan itu "berantakan dengan
system" karena tidak merusak pengelola paket, dan sementara itu bisa
menimpa paket yang diinstal sistem (yang tinggal di
/usr/lib/pythonX.Y/dist-packages), ia melakukannya dengan cara yang terdefinisi dan terdokumentasi.

  1. Instal ke --user , ini akan melindungi dari sistem yang rusak (saya pikir?)
    tapi saya tidak berpikir siapa pun akan mengharapkan pengguna root untuk mendapatkan
    /root/.local/ pasang.

Setuju, itu tidak terduga.

  1. Hanya kesalahan dan meminta pengguna untuk memilih --user atau
    --global secara manual.

Saya akan baik-baik saja dengan itu, tetapi lihat sakelar konfigurasi di atas.

  1. Pilih salah satu dari dua opsi pertama, tetapi sediakan sakelar yang dapat digunakan oleh distro
    masukkan /etc/ yang akan mengaktifkan opsi ketiga.

Hei, pilihan yang bagus!

Opsi keempat mungkin yang terbaik tetapi saya merasa kita harus mencoba
pilih salah satu opsi lain terlebih dahulu jika kita dapat menemukan semacam solusi
yang bekerja sama di semua platform/skenario dan masuk akal untuk semuanya
karena saya lebih suka memiliki perilaku lintas platform yang konsisten jika memungkinkan.

Saya baik-baik saja dengan memiliki perilaku berbeda yang ditentukan platform, jika katakanlah, pip memiliki
--dry-run opsi yang setidaknya akan memberi tahu pengguna apa yang sebenarnya terjadi
untuk dilakukan dan di mana.

Saya merasa opsi ketiga kemungkinan besar adalah pilihan yang buruk, karena "Saya telah menulis
izin" akan menjadi skenario yang digunakan siapa pun di Windows sebelum
Python 3.5, atau siapa saja yang menggunakan Conda, atau siapa saja yang menggunakan pyenv. Kesalahan
sepertinya hal yang salah untuk dilakukan dalam semua kasus itu dan sangat pengguna
tidak ramah untuk boot.

Saya akan senang jika konfigurasi default mengizinkan --global install jika Anda
memiliki izin. Saya bahkan tidak berpikir Debian akan mengubahnya (mungkin yang lain sudah
pendapat yang berbeda, tapi setidaknya itu memberi kita pilihan).

Jadi saya kira antara 1 dan 2 itu benar-benar tergantung pada seberapa buruk praktiknya
kami pikir orang-orang (secara konseptual) harus melakukan sudo pip install --global foo .

Di Debian, ini adalah kasus penggunaan yang diharapkan, asalkan masuk ke /usr/local/lib.
Itu tidak bisa pergi ke /usr/lib.

(Semua ini menjelaskan perilaku luar-a-venv-BTW.)

  • Ketika --user dilewatkan, kami selalu menginstal ke dalam paket situs pengguna.

+1

  • Ketika --global dilewatkan, kami selalu menginstal ke situs global
  • paket.

Paket _vendor_ global == +1, paket situs global == -1.

  • Ketika tidak ada yang dilewati, kami menerapkan metode fallback yang:

    1. Mendeteksi jika kita berada di lingkungan virtual dan jika demikian bertindak seolah-olah

      --global telah berlalu.

+1, meskipun saya akan mengulangi bahwa direktori ini di dalam venv bernama
/lib/pythonX.Y/site-packages

  1. Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah
    --global telah berlalu.

Hmm, saya tidak yakin tentang yang satu ini.

  1. Lihat default-install dan jika ada gunakan --user atau
    -global berdasarkan itu.

+1

  1. Mendeteksi jika pengguna efektif tidak memiliki izin menulis ke global
    paket situs, dan jika mereka tidak bertindak seolah-olah --user dilewatkan.

+1

  1. Terakhir, jika semua metode deteksi lainnya gagal, bertindaklah seolah-olah --global
    telah berlalu.

Juga tidak yakin.

Ini berarti tidak ada periode penghentian dan harapannya adalah bahwa dalam
tidak adanya --user atau --global kami akan mencoba membuat tebakan terbaik berdasarkan
pada kemampuan Python yang kami jalankan, pengguna yang efektif, dan
semua metode penginstalan default yang dikonfigurasi.

Kedengarannya seperti tujuan yang masuk akal.

Untuk lebih jelasnya, ketika saya berbicara tentang "paket situs global", maksud saya terutama "apa pun yang distutils memberitahu kita untuk menginstal sesuatu secara global". Karena Python sendiri tidak memiliki perbedaan "vendor lokal" vs "situs lokal", ini akan menjadi direktori yang sama di hilir mana pun yang tidak menambal Python mereka. Namun pada debian itu akan benar-benar menjadi direktori dist-packages dan "global" sebenarnya berarti "situs lokal". Itu bukan sesuatu yang pip perlu lakukan sesuatu yang istimewa untuk didukung karena itu diurus oleh tambalan Debuntu ke Python.

Dengan kata lain, pip sudah menginstal ke /usr/local/../dist-packages/ di Debuntu karena Debuntu telah menambal distutil untuk mendukung perbedaan itu. Satu-satunya waktu pip akan mengacaukan /usr/../dist-packages/ tanpa pengguna mengirimkan semacam flag adalah bahwa pip akan menghapus file dari sana (karena pip tidak melihat direktori itu sebagai khusus, itu hanya melihatnya sebagai sesuatu pada sys.path ). Debian telah menambal pip untuk mencegah pencopotan itu dari sana, dan saya pikir dukungan nyata untuk itu tergantung pada mendapatkan dukungan nyata untuk paket situs "vendor lokal" di Python upstream.

Kami mungkin menginginkan semacam peringatan jika kami menginstal ke --user dan ~/.local/bin tidak ada di $PATH

Seberapa rapuhkah peringatan ini? Apakah itu akan dikonversi ke jalur absolut? Apakah ini akan menjadi case-sensitive pada sistem file case-insensitive? Apakah itu akan memperlakukan dan / sebagai setara pada Windows? Bagaimana dengan symlink?

Jika Anda menginstal paket yang tidak menginstal skrip apa pun, peringatan itu tetap tidak relevan.

Secara pribadi, saya pikir peringatan mungkin akan lebih berbahaya daripada baik.

Kami mungkin menginginkan semacam peringatan jika kami menginstal ke --user dan
~/.local/bin tidak ada di $PATH .

+1, mungkin dengan opsi konfigurasi untuk menekan peringatan?

Kita bisa membuatnya menggunakan peringatan Python sehingga orang bisa diam saja
itu menggunakan peringatan Python bawaan. Jika kita merasa perlu untuk membungkamnya di
semua.

Pada pip 6.0 kami memiliki file konfigurasi khusus mesin yang terletak di /etc/
namun ini tidak spesifik untuk versi Python yang dijalankan
pip. Saya pikir itu fitur yang bagus meskipun agak terpisah juga (dan
mungkin berjalan seiring dengan memecahkan masalah skrip juga).

Saya akan menyarankan urutan pencarian seperti:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

di-root dulu(?) di /etc/xdg/pip lalu /etc, di mana XY tentu saja adalah
nomor versi mayor.minor. Yang pertama ditemukan, menang.

Bagi ini menjadi #2417 karena saya yakin ini hanya terkait dengan ini
diskusi.

Saya melihat satu pertanyaan besar yang masih terbuka: Jangka panjang apa yang kita inginkan terjadi ketika
seseorang melakukan sudo pip install foo atau lebih tepatnya, jika seseorang memiliki izin untuk
menulis ke direktori site-packages ?

Harap dicatat bahwa tidak hanya ada satu direktori "paket situs". Sebagai contoh,
di Debian/Ubuntu kita tidak ingin sudo pip install untuk _ever_ install ke
/usr/lib, tetapi hanya /usr/local/lib. Dan jangan lupa, ini adalah paket-paket di sini
bukan paket situs (kecuali di ~/.local karena $reasons).

Ini benar-benar poin penting yang terkadang dilupakan (bahkan oleh saya).
Donald menggambarkannya dengan baik ketika dia mengatakan ada direktori situs-lokal dan a
direktori vendor-lokal. Di Debian, situs-lokal adalah
/usr/lib/pythonX.Y/dist-packages dan tidak ada perintah pip yang boleh menyentuhnya,
sementara vendor-local adalah /usr/local/lib/pythonX.Y/dist-packages dan itu adalah
kasus penggunaan yang didokumentasikan dan populer untuk beberapa administrator sistem untuk menginstal pip
ke dalam direktori itu.

Jadi yang saya sarankan, karena kita sudah menelusuri jalur file konfigurasi, adalah untuk
buat ini dapat dikonfigurasi, mis

  • global_install_directory
  • global_install_as_sudo (benar/salah)

pip tidak benar-benar mengontrol ini (maksud saya, jelas pada level tinggi itu
karena itu yang memindahkan file), mereka berasal dari distutils/sysconfig.

Saya pikir pip mungkin tidak boleh menyentuh direktori vendor-lokal kecuali
semacam bendera diberikan seperti --vendor yang akan memungkinkan vendor untuk menggunakan
pip dalam rantai build mereka. Konsep ini tidak benar-benar ada di luar debuntu
sekarang dan tambalan mereka sudah menangani ini, jadi menurut saya itu tidak super
relevan dengan diskusi ini kecuali untuk dicatat bahwa ketika saya mengatakan
"paket situs global" maksud saya /usr/local/.../dist-packages di Debubuntu
dan paket "situs-lokal" di beberapa titik jika Python menerima Debuntu
sistem hulu.

  1. Instal ke --global . Ini adalah opsi yang paling kompatibel dengan versi sebelumnya
    dan kemungkinan mewakili apa yang diharapkan pengguna saat mereka mengetiknya. Namun memiliki
    kelemahannya adalah (diam-diam) mengacaukan Python global, yang pada banyak
    sistem dapat menyebabkan sistem rusak.

Dengan konfigurasi di atas, ini akan sepenuhnya kompatibel dengan Debian.
Pengguna super Debian mengharapkan sudo pip install untuk masuk
/usr/local/lib/pythonX.Y/dist-packages. Saya tidak akan mengatakan itu "berantakan dengan
system" karena tidak merusak pengelola paket, dan sementara itu bisa
menimpa paket yang diinstal sistem (yang tinggal di
/usr/lib/pythonX.Y/dist-packages), ia melakukannya dengan cara yang terdefinisi dan terdokumentasi.

Ya, "mengacaukan sistem" mungkin terlalu keras. Kebanyakan maksud saya itu
sudo pip install foo dapat merusak sesuatu jika sistem bergantung pada foo dan
Anda menginstal versi yang tidak kompatibel. Namun kasus yang sama berlaku
true untuk semua yang Anda instal ke`/usr/local``.

  • Ketika --global dilewatkan, kami selalu menginstal ke situs global
  • paket.

Paket _vendor_ global == +1, paket situs global == -1.

Maksudmu ini sebaliknya kan?

  • Ketika tidak ada yang dilewati, kami menerapkan metode fallback yang:

    1. Mendeteksi jika kita berada di lingkungan virtual dan jika demikian bertindak seolah-olah

      --global telah berlalu.

+1, meskipun saya akan mengulangi bahwa direktori ini di dalam venv bernama
/lib/pythonX.Y/site-packages

Ya, lagi-lagi kami hanya menanyakan Python di mana direktori itu, kami tidak menghitungnya
diri kita sendiri, jadi "di mana direktori itu" adalah hal venv/virtualenv.

  1. Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah
    --global telah berlalu.

Hmm, saya tidak yakin tentang yang satu ini.

Saya tidak berpikir ada cara untuk mengatasi ini, jika paket situs pengguna dinonaktifkan, saya
jangan berpikir bahwa kita harus menginstal ke sana karena kita tidak memiliki cara untuk mengetahuinya
jika penonaktifan itu berarti _is_ tidak ada paket situs pengguna, atau mengapa. Kami hanya bisa
menganggap bahwa tidak ada.

  1. Terakhir, jika semua metode deteksi lainnya gagal, bertindaklah seolah-olah --global
    telah berlalu.

Juga tidak yakin.

Ini pada dasarnya bermuara pada:

Jika kami belum menemukan alasan, kami harus menggunakan --user, seperti --user flag, atau
tidak memiliki izin untuk menulis ke direktori, maka jangan menggunakannya. Ini
adalah apa yang akan membuat sudo pip install foo tanpa flag --global
bekerja. Ini juga berarti ini adalah aturan yang paling penting untuk tidak melanggar
perangkat lunak yang berfungsi yang mengharapkan sudo pip install foo untuk bertindak seperti ini.

Kami mungkin menginginkan semacam peringatan jika kami menginstal ke --user dan ~/.local/bin tidak ada di $PATH

Seberapa rapuhkah peringatan ini? Apakah itu akan dikonversi ke jalur absolut? Apakah ini akan menjadi case-sensitive pada sistem file case-insensitive? Apakah itu akan memperlakukan dan / sebagai setara pada Windows? Bagaimana dengan symlink?

Jika Anda menginstal paket yang tidak menginstal skrip apa pun, peringatan itu tetap tidak relevan.

Secara pribadi, saya pikir peringatan mungkin akan lebih berbahaya daripada baik.

Yah kita bisa mengimplementasikannya sebagai (setara lintas platform):

def user_bin_on_path():
    paths = os.environ.get("PATH").split(":")
    for path in paths:
        if os.path.realpath(path) == os.path.realpath(USER_BIN_DIR):
            return True
    return False

Sesuatu seperti itu harus menangani symlink, pemisah jalur, dan sejenisnya menurut saya. Setan dalam detailnya dan mungkin kita tidak bisa cukup akurat untuk menutupi berbagai kasus sudut lintas platform.

Saya setuju bahwa peringatan itu tidak relevan jika tidak ada skrip yang diinstal, dan saya bermaksud mengatakan bahwa kami hanya akan repot dengan peringatan ketika kami menginstal skrip.

Ide dasarnya adalah saya tidak ingin seseorang melakukan sesuatu seperti pip install [--user] foo di mana --user tersirat, dan kemudian melakukan foo dan mendapatkan "perintah tidak ditemukan" tanpa panduan tentang mengapa mungkin tidak ditemukan. Peringatan setidaknya akan memberi tahu mereka bahwa mereka perlu menambahkan sesuatu ke PATH. Ini juga dapat membantu meminta pengguna di Windows untuk menambahkan direktori pengguna mereka ke PATH mereka secara manual (atau menjalankan beberapa skrip untuk melakukannya) yang mungkin mengurangi kebutuhan akan skrip activate yang ditunjukkan Steve. Meskipun saya pikir itu masih berarti bahwa nilai Sistem lebih diutamakan daripada nilai pengguna sehingga masih mungkin membingungkan karena urutan PATH dan sys.path akan tetap dibalik.

Doh. Saya lupa bahwa realpath mengkanonikalisasi jalur. Ya, tentu saja itu bekerja dengan cukup baik.

Hal yang mengganggu saya adalah bahwa _jika_ tes keliru melihat masalah, pengguna mendapat peringatan yang mengganggu dan salah tanpa cara untuk menghindarinya selain mengubah sistem mereka untuk mengatasi kesalahan pada bagian pip. Tetapi mengingat bahwa pengujian yang Anda usulkan mungkin cukup kuat, dan kami hanya melakukan pemeriksaan jika kami memasang skrip, masalahnya mungkin cukup jarang untuk diabaikan.

Baiklah, saya pikir kita memiliki beberapa kesepakatan luas di sini. Saya pikir langkah selanjutnya adalah mendapatkan tambalan. Saya akan pergi ke depan dan mencoba untuk mendapatkan sesuatu nanti malam atau besok.

Pada 10 Februari 2015, pukul 12:14, Donald Stufft menulis:

Ide dasarnya adalah saya tidak ingin seseorang melakukan sesuatu seperti pip install [--user] foo di mana --user tersirat, dan kemudian melakukan foo dan
dapatkan "perintah tidak ditemukan" tanpa panduan apa pun tentang mengapa itu tidak terjadi
ditemukan.

Debian, dan mungkin Linux lainnya, sebenarnya memiliki paket command-not-found
yang meminta pengguna untuk menginstal sebuah paket jika mereka menjalankan perintah yang
tidak diinstal.

% lanskap tinta
Program 'inkscape' saat ini tidak diinstal. Anda dapat menginstalnya dengan mengetik:
sudo apt-get install inkscape

Mungkin kita bisa menghubungkannya dengan platform pendukung.

Pada 10 Februari 2015, pukul 12:06, Donald Stufft menulis:

  • Ketika --global dilewatkan, kami selalu menginstal ke situs global
  • paket.

Paket _vendor_ global == +1, paket situs global == -1.

Maksudmu ini sebaliknya kan?

Saya dapat mencampuradukkan terminologi saya, jadi saya akan secara eksplisit:

/usr/local/lib/pythonX.Y/dist-packages == +1
/usr/lib/pythonX.Y/dist-packages == -1

tetapi seperti yang Anda katakan sebelumnya, ini bukan sesuatu yang benar-benar perlu dikhawatirkan pip
tentang sejak itu diwarisi dari distutil dan distutil Debuntu ditambal
untuk melakukan hal yang benar.

  1. Mendeteksi jika paket situs pengguna dinonaktifkan dan jika demikian bertindak seolah-olah
    --global telah berlalu.

Hmm, saya tidak yakin tentang yang satu ini.

Saya tidak berpikir ada cara untuk mengatasi ini, jika paket situs pengguna dinonaktifkan, saya
jangan berpikir bahwa kita harus menginstal ke sana karena kita tidak memiliki cara untuk mengetahuinya
jika penonaktifan itu berarti _is_ tidak ada paket situs pengguna, atau mengapa. Kami hanya bisa
menganggap bahwa tidak ada.

Oh, aku mengerti maksudmu sekarang. Saya rasa itu masuk akal. Kekhawatiran saya adalah bahwa itu
mungkin lebih sulit untuk memprediksi apa yang sebenarnya akan dilakukan pip, tetapi seperti yang saya
katakan, saya akan senang dengan flag --dry-run sehingga pip dapat dengan tegas _memberi tahu_
Anda apa yang akan dilakukan.

  1. Terakhir, jika semua metode deteksi lainnya gagal, bertindaklah seolah-olah --global
    telah berlalu.

Juga tidak yakin.

Ini pada dasarnya bermuara pada:

Jika kami belum menemukan alasan, kami harus menggunakan --user, seperti --user flag, atau
tidak memiliki izin untuk menulis ke direktori, maka jangan menggunakannya. Ini
adalah apa yang akan membuat sudo pip install foo tanpa flag --global
bekerja. Ini juga berarti ini adalah aturan yang paling penting untuk tidak melanggar
perangkat lunak yang berfungsi yang mengharapkan sudo pip install foo untuk bertindak seperti ini.

Saya melihat. Saya pikir tidak apa-apa, karena kasus anti-penggunaan utama yang ingin kita hindari adalah:

normal_user$ pip install foo
HAI ANDA TIDAK MEMILIKI IZIN
normal_user$ sudo pip install foo
HAI ANDA HANYA MEMBORK SISTEM ANDA

dan aturan "tidak memiliki izin untuk menulis ke direktori menyiratkan --pengguna"
mengurus itu.

Oh ya saya lupa tentang command-not-found. Bisa berguna. Omong-omong, apakah Anda tahu tempat yang tepat untuk mengusulkan bahwa devubtu memiliki bin lokal pengguna di jalur secara default?

Pada 10 Februari 2015, pukul 16:05, Barry Warsawa [email protected] menulis:

Pada 10 Februari 2015, pukul 12:14, Donald Stufft menulis:

Ide dasarnya adalah saya tidak ingin seseorang melakukan sesuatu seperti pip install [--user] foo di mana --user tersirat, dan kemudian melakukan foo dan
dapatkan "perintah tidak ditemukan" tanpa panduan apa pun tentang mengapa itu tidak terjadi
ditemukan.

Debian, dan mungkin Linux lainnya, sebenarnya memiliki paket command-not-found
yang meminta pengguna untuk menginstal sebuah paket jika mereka menjalankan perintah yang
tidak diinstal.

% lanskap tinta
Program 'inkscape' saat ini tidak diinstal. Anda dapat menginstalnya dengan mengetik:
sudo apt-get install inkscape

Mungkin kita bisa menghubungkannya dengan platform pendukung.


Balas email ini secara langsung atau lihat di GitHub.

Pada 10 Februari 2015, pukul 13:17, Donald Stufft menulis:

Oh ya saya lupa tentang command-not-found. Bisa berguna. Ngomong-ngomong, apakah kamu?
tahu tempat yang tepat untuk mengusulkan bahwa devubtu memiliki bin lokal pengguna di
jalur secara default?

Tidak secara pasti, tapi mungkin paket adduser atau passwd? Mantan memiliki
/usr/sbin/adduser dan yang terakhir memiliki /usr/bin/useradd.

Saya tidak yakin apakah ini membantu, tapi…

  • ~/.local/bin tidak ada di $PATH banyak orang, apakah ada yang bisa dilakukan tentang ini?

Beberapa proyek lain menggunakan /etc/profiled.d/ untuk menambahkan direktori ke $PATH. Setidaknya di Antergos saya melihat yang berikut (kecuali saya salah paham apa fungsinya) jre.csh, jre.sh, perlbin.csh, perlbin.sh.

# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
setenv PATH "${PATH}:/usr/lib/jvm/default/bin"
# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
export PATH=${PATH}:/usr/lib/jvm/default/bin
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && setenv PATH ${PATH}:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && setenv PATH ${PATH}:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && setenv PATH ${PATH}:/usr/bin/core_perl

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl

export PATH

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2

Sebagai pengguna pip acak, saya hanya ingin mengucapkan _terima kasih_ karena telah menangani masalah pengalaman pengguna seperti ini dan seperti yang lainnya yang terekam dalam tonggak Tingkatkan Pengalaman Pengguna kami . Apakah ada tempat saya dapat berkontribusi secara finansial untuk upaya ini?

Selain itu, saya menggunakan Homebrew dan selalu menghargai kenyataan bahwa saya hanya bisa brew install something dan itu akan berhasil tanpa masalah izin.

Setelah saya mengerti mengapa menginstal dengan Homebrew tidak pernah membutuhkan sudo , saya mencoba membiasakan diri melakukan pip install --user something , tetapi ironisnya Homebrew menonaktifkan ini karena bug yang dilaporkan di distutils.

Mengingat popularitas Homebrew di OS X, mungkin Anda semua ingin melihat ketidakcocokan Homebrew dan pip install --user ini.

Bagaimanapun, +1 dari saya untuk menjadikan --user sebagai default.

Tindak lanjut yang cepat. Didier mengunggah perubahan ke pip Ubuntu dengan jelas yang menetapkan --user sebagai default. Saya kebanyakan juga mengizinkannya tetapi sekarang saya pikir itu adalah kesalahan dan saya bermaksud untuk mengembalikannya dengan cerdik (tapi mungkin tidak akan SRU perubahan untuk hidup). Lihat https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1460203 untuk detail dan alasan.

+1 untuk membiarkan upstream mendorong waktu perubahan ini, karena perbedaan pengguna vs sistem sudah cukup membingungkan tanpa perbedaan platform ikut bermain.

Yang mengatakan, mungkin masuk akal untuk distro Linux untuk mulai membalik default ke --user segera setelah --dukungan global mendarat di pip upstream (pip 8?), Sejak melakukan instalasi global di Linux, daripada per-pengguna atau per-venv menginstal, mapan sebagai ide yang buruk dengan efek samping yang berpotensi tak terduga.

Saya memberi tahu @warsaw secara pribadi, tetapi saya juga akan mengatakannya di sini:

Saya pikir perubahan ini penting dan saya berencana untuk kembali ke permintaan tarik saya untuk menyelesaikannya. Namun, saya adalah satu orang yang terlibat dalam beberapa proyek dan saat ini Gudang lebih penting bagi saya daripada perubahan ini karena warisan PyPI menjadi semakin memberatkan untuk dioperasikan dan saya merasa kami perlu menggantinya sesegera mungkin. Oleh karena itu waktu saya di pip tidak berfokus pada membuat banyak perubahan sendiri, melainkan berfokus pada membimbing melalui perubahan yang dibuat kontributor lain serta hal-hal proses rilis apa pun.

Karena itu, jika ada yang benar-benar peduli dengan fitur ini yang akan mendarat lebih cepat daripada nanti, mereka dapat mengambil pekerjaan saya dan menyelesaikannya dan saya akan dengan senang hati meninjau (dan mudah-mudahan menggabungkannya). Saya senang membicarakannya dengan siapa saja yang ingin melakukannya dan memberikan panduan tentang perubahan itu. Kalau tidak, itu akan menunggu sampai saya menyelesaikan item yang lebih mendesak bagi saya.

Mungkin layak untuk diulang pada saat ini:

Jika kami akhirnya memutuskan untuk tidak menggunakan 'default ke --user', kami harus mempertimbangkan alternatif yang tidak terlalu mengganggu

  1. Kembali ke --user (jika pemasangan gagal karena kesalahan izin)
  2. (Jika pemasangan gagal karena kesalahan izin), dorong pengguna (dalam huruf besar yang bersahabat) untuk mencoba --user

FWIW, sekarang penginstal Windows untuk Python 3.5 sangat mendorong penginstalan per pengguna, saya tidak begitu khawatir tentang perubahan yang terjadi di pip. Itu mungkin akan membuat opsi konfigurasi yang lebih baik untuk distro (dengan --global override) daripada default baru atau fallback.

Hanya ingin memberi +1 pada masalah ini dan mengucapkan terima kasih telah mengerjakan ini! Kami menjalankan sekolah musim panas Python ilmiah saat ini dan memiliki banyak orang sudo pip install ketika mereka mengalami masalah izin.

FWIW Saya mendukung default ke --user , atau kembali ke --user jika pemasangan gagal karena kesalahan izin. Dalam hal ini, saya lebih suka memberi mereka petunjuk untuk membalikkan apa yang telah mereka lakukan (misalnya, We installed to your user directory. If you don't want this, then 'pip uninstall my_package' ) daripada gagal dan memberi tahu mereka cara mencoba lagi.

Saya melihat banyak laporan bug pada tiruan karena --user - setidaknya di Ubuntu di mana --user's tempat di jalur setelah dist-paket, dan pip apa yang diinstal sebenarnya tidak digunakan, untuk ketergantungan umum (seperti enam) yang ada di dist-paket.

Mereka meletakkannya _after_ dist-packages ? Itu IMO instalasi yang rusak.

Benar, pemasangan pengguna harus sebelum paket situs(/dist), dan kemudian skrip & utilitas sistem harus dijalankan dengan -I (atau -Es di Python 2).

Ya saya setuju :). Ini mungkin diperbaiki dengan jelas, tetapi saya pasti melihat laporan di mana segala sesuatunya berasal dari tempat yang benar-benar salah.

Saya baru saja menggunakan pip sistem untuk menginstal setuptools pada mesin hidup saya, untuk bereksperimen.

>>> import setuptools
>>> setuptools.__path__
['/home/robertc/.local/lib/python2.7/site-packages/setuptools']
>>> import sys
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/robertc/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/home/robertc/work/mock']

Jadi yang satu ini waras. Tapi membingungkan ini diperkenalkan dengan jelas - jadi IDK. Saya akan melihat apakah saya dapat menggali reproduksi di beberapa titik (untuk file di BTS Ubuntu)

Halaman @warsaw

Paket situs pengguna dapat diatur ulang setelah paket situs global oleh file evil .pth setuptools. Ini adalah masalah yang berulang bagi saya sampai saya belajar untuk tidak pernah menggunakan setup.py secara langsung - saya akan menginstal sesuatu, dan tiba-tiba saya menggunakan versi yang lebih lama dari semua jenis hal lainnya. Setelah beberapa kali, saya menulis alat agresif untuk membongkar sistem saya.

Saya pikir setidaknya, untuk saat ini, pip seharusnya hanya mencetak pesan ramah yang meminta pengguna untuk menjalankan --user jika perintah gagal. Meskipun mengubahnya menjadi default memiliki manfaat, mencetak pesan yang lebih baik seharusnya tidak terlalu sulit.

Ini adalah "perbaikan cepat" yang bagus untuk masalah sampai kita benar-benar pindah ke default ke --user .

--global, --system, atau --no-user juga diperlukan jika mode pengguna diatur di /etc/pip.conf. Tidak ada cara mudah bagi pengguna untuk mengesampingkan ini sejauh yang saya tahu.

Ini adalah "perbaikan cepat" yang bagus untuk masalah ini

Pembaruan terlambat: #4233 melakukan ini.

Orang (terutama pendatang baru) yang tidak menggunakan Windows harus benar-benar diarahkan ke https://github.com/pyenv/pyenv jika mereka ingin memiliki pengalaman yang baik. PEP 370 tidak terlalu masuk akal bagi saya hari ini, terutama karena ~/.local adalah XDG_DATA_HOME.

Saya pikir saya tidak akan menjadi satu-satunya yang akan memilih keluar dari perilaku ini jika/ketika itu datang. Semoga transisinya lancar dan saya tidak perlu mengubah cara kerja sistem saya dan meneruskan flag CLI tambahan, karena saya cukup senang dengan pyenv. Tentu saja, saya tidak tahu seberapa baik pyenv bekerja dengan Windows tetapi subsistem bash dapat membantu di sana ...

@jcrben pyenv membuat beberapa asumsi tentang bagaimana orang menggunakan Python (dan khususnya bagaimana mereka memperoleh binari Python mereka), yang berarti itu bekerja sangat baik untuk orang-orang yang asumsinya valid, tetapi tidak cukup universal untuk menjadi rekomendasi default (dalam hal ini mirip dengan conda ).

--user default pada level pip tidak akan berpengaruh di dalam lingkungan virtual Python yang dikonfigurasi dengan benar, jadi dampak dari perubahan ini pada pengelola lingkungan pihak ketiga seperti conda dan pyenv adalah bahwa mereka harus memastikan bahwa mereka memberi sinyal status lingkungan dengan benar dengan cara yang akan dideteksi oleh pip dan alat lain (yaitu cara virtualenv melaporkannya, atau cara yang dilakukan perpustakaan standar venv ).

~Apakah mengizinkan pengguna untuk menyesuaikan direktori (mungkin melalui variabel env) untuk menghindari menginstal langsung ke ~/.local telah dipertimbangkan? Saya mungkin lebih suka menyarangkannya ke ~/.local/pip atau sesuatu - sejauh yang saya ketahui Python tidak memiliki hak khusus ke tingkat atas ruang bersama itu. ~ Pada 9.0.1 tampaknya menumpuk barang-barang di bawah ~/.local/lib/python<version> plus menambahkan executable ke ~/.local/bin yang menurut saya baik-baik saja ...

@jcrben Ya, lokasi target sebenarnya adalah direktori situs pengguna Python, yang mencerminkan skema penamaan untuk direktori paket situs sistem: https://docs.python.org/3/library/site.html#site.USER_SITE

Itu sudah dapat dikonfigurasi di tingkat juru bahasa melalui variabel lingkungan PYTHONUSERBASE : https://docs.python.org/3/using/cmdline.html#envvar -PYTHONUSERBASE

Bagi mereka yang tertarik, saya baru saja merilis https://github.com/ofek/hatch yang memiliki perintah paket install , uninstall , dan update yang default untuk perilaku ini. Untuk mengubah sistem, pengguna dapat menggunakan opsi -g/--global yang mirip dengan https://github.com/npm/npm.

Mengingat masalah baru-baru ini dengan paket yang terinfeksi malware di PyPI , saya pikir itu kepentingan terbaik pip untuk melakukan apa yang dapat dilakukan untuk mencegah penggunaan sudo pip install ... , terutama dengan mempertimbangkan bahwa skrip pengaturan dapat mengeksekusi kode arbitrer pada instalasi. Menginstal paket yang terinfeksi sebagai pengguna sudah cukup buruk, tetapi jauh lebih buruk jika diinstal sebagai root.

Default ke instalasi pengguna berarti lebih sedikit orang yang akan menambahkan sudo ke perintah pip mereka, yang berarti malware yang diinstal secara tidak sengaja dapat melakukan lebih sedikit.

Sebagai langkah konkret berikutnya, saya memecahkan masalah terpisah untuk penambahan flag --global : https://github.com/pypa/pip/issues/4865

Ini hampir pasti merupakan ide yang buruk di lingkungan virtualenv atau conda. Apa pun yang dipasang di .local ketika satu lingkungan aktif dapat dengan mudah merusak lingkungan lain. Jadi apa yang dipikirkan dalam kasus-kasus itu?

cc @marahan @kalefranz

Masalah ini tidak berlaku saat berada di dalam lingkungan virtual aktif - hanya berlaku saat tidak ada lingkungan aktif yang terdeteksi, dan tidak ada opsi definisi target ( --prefix , --root , dll) telah diberikan pada baris perintah.

Bagaimana ini ditentukan?

Kami telah mempertimbangkan untuk menonaktifkan secara default ~/.local pada sys.path untuk python di dalam lingkungan conda, yang menurut definisi adalah python yang diinstal oleh conda. Ini rumit. Bagaimanapun, kami mungkin akan melanggar ekspektasi sekelompok pengguna. Diskusi di https://github.com/conda/conda/issues/7173

Tidakkah pip dapat memuat argumen apa pun dari variabel lingkungan yang dimulai dengan PIP_ ? Apakah ini bekerja untuk --user ? Apa yang akan menjadi nama variabel lengkap?

Itu akan menjadi PIP_USER .

Dokumen: https://pip.pypa.io/en/stable/user_guide/#environment -variables

PIP_USER=yes tepatnya, terima kasih! Menggunakan variabel lingkungan jauh lebih mudah untuk penggunaan CI karena Anda hanya perlu mendefinisikannya satu kali dan variabel tersebut akan digunakan kapan pun perintah dipanggil.

Saya harus melakukan logika yang sangat jelek untuk travis di mana tampaknya beberapa tahapan dijalankan sebagai pengguna normal tanpa virtualemv dan beberapa di dalam virtualenv, dan Anda tidak tahu yang mana itu.

di dalam virtualenv kemungkinan —pengguna akan gagal jika Anda tidak menggunakan paket situs (yang menyebabkan masalah lain).

Ini yang saya harus mendeteksi virtualenv di bash dan menghindari menambahkan —pengguna atau proses akan gagal.

Ini jelek dan menyebabkan saya membuang banyak waktu untuk debugging, saya yakin orang lain akan menghadapi hal yang sama.

Saya pikir kita memerlukan opsi yang mengaktifkan fallback terkait instalasi: seperti menginstalnya pada pengguna jika Anda bisa dan mundur ke sistem.

pip seharusnya gagal hanya jika gagal menemukan tempat untuk menginstal sebuah paket.

Setiap gerakan ini?

Saya tidak melihatnya disebutkan, tetapi mungkin pip harus mengeluh jika --user dilewatkan saat dijalankan di bawah Sudo.

Masalah yang belum terpecahkan ini membuat pemrogram menjauh dari pip dan bahkan python dan memaksa mereka untuk menggunakan paket lain atau bahkan bahasa pemrograman lain seperti javascript dan npm dengan lebih sedikit masalah seperti ini. Untuk pemula baru yang ingin menggunakan python, opsi tambahan yang diperlukan ini membuat frustrasi.

Mengapa --user menjadi default? Tidak bisakah itu ditentukan secara eksplisit? Saya tidak dapat menjalankan pip --target karena itu mengeluh bahwa itu tidak dapat digunakan bersama dengan pengguna. Adakah ide bagaimana menghindarinya?

@dmikov : itu bukan default. Kecuali jika Anda menggunakan versi rusak Debian/Ubuntu , dalam hal ini Anda dapat mengatasi --user secara otomatis disetel dengan menggunakan: PIP_USER=0 pip install -t ... . Atau lebih baik lagi, instal versi resmi dan gunakan itu.

Saya bermimpi di malam hari opsi --user menjadi default (tidak bercanda), apakah ada kemungkinan impian saya menjadi kenyataan dalam waktu dekat?

Saya butuh bantuan untuk menginstal pygame yang terus mengatakan sintaks tidak valid

saya menggunakan
python3 -m pip install -U pygame --user
apakah ini salah apa yang harus saya lakukan?

@flamedro56 : alih-alih mengomentari masalah acak, silakan buka yang baru, dan berikan informasi lebih lanjut: Versi Python, versi pip, sistem operasi, keluaran perintah...

Pemasang reCAPTCHA

Bagaimana dengan memiliki opsi konfigurasi baru default=system,user? Itu akan cukup eksplisit sehingga tidak ada yang akan berpikir itu berarti "selalu pengguna, bahkan di virtualenv". Itu akan memungkinkan jalur migrasi yang anggun.

Lihat #4575.

Sepertinya Manjaro mencoba mengatur --user sebagai default.

Apakah ada yang baru dari hulu tentang masalah ini?

@Tids : "filesystem-2018.9-3 menambahkan $HOME/.local/bin ke $PATH Anda secara default." adalah bagian ekstra kunci yang Manjaro lakukan dengan benar.

Debian menggabungkan "default ke --user" di tingkat Python dengan "$HOME/.local/bin tidak ada di $PATH Anda secara default" di tingkat akun pengguna, dan itulah kombo yang merusak banyak hal.

Di #7002, saya mencoba membuat pip melakukan instalasi pengguna secara default ketika direktori paket situs global tidak dapat ditulisi, dan paket situs pengguna diaktifkan. Ini sebagian besar harus menghindari melakukan instalasi pengguna ketika Anda bermaksud menginstal ke dalam env, selama Anda memiliki izin untuk memodifikasi env.

Saya mencari diskusi tentang idenya terlebih dahulu - jangan terpaku untuk meninjau implementasi sebelum kita memikirkan apakah masuk akal untuk melakukan hal itu sama sekali.

Perlu dicatat bahwa mencampur pemasangan pengguna dan pemasangan non-pengguna (dari pip itu sendiri) penuh dengan masalah - lihat #7209 sebagai salah satu contoh baru-baru ini.

Meskipun tidak secara langsung terkait dengan masalah ini (dan memang jika kita menggunakan default ke pengguna, itu mungkin agak meringankan situasi) ini menekankan perlunya pemikiran yang cermat tentang bagaimana kita menangani transisi apa pun ke --user sebagai default.

(Saya terutama menambahkan komentar ini di sini sehingga direkam di suatu tempat - sebagian besar bukan masalah pip sama sekali, melainkan komplikasi dari cara kerja direktori USER_SITE Python secara umum, yang tidak cukup dipahami dengan baik oleh pengguna yang menginstal dengan --user ).

Sepertinya masalahnya adalah PATH (untuk menemukan perintah) dan sys.path (untuk menemukan impor Python) memiliki prioritas yang berlawanan, jadi skrip peluncur dari satu instalasi mencoba memuat paket dari lainnya. Ini mungkin tidak spesifik untuk pip - ini dapat memengaruhi paket apa pun yang menginstal skrip.

Saya tidak yakin apa, jika ada, yang bisa kita lakukan tentang itu, tapi saya setuju itu layak untuk dipikirkan.

Ya, itulah "komplikasi USER_SITE" utama yang saya pikirkan. IMO, menghentikan skrip pembungkus dan hanya mendukung python -m pip adalah solusi paling efektif. (Saya tidak menentang pembungkus itu sendiri, tetapi masalah yang kita lihat pada mereka biasanya adalah orang-orang secara tidak sengaja menjalankan pembungkus yang salah , jadi memperbaiki masalah skrip pembungkus biasanya bukan masalah pip, lebih dari "mendiagnosis dan memperbaiki kesalahan konfigurasi lingkungan pengguna " isu)

Maksud Anda menghentikan skrip pembungkus pip , atau menghentikan skrip pembungkus sebagai sesuatu yang dapat dipasang oleh pip?

Saya yakin -1 pada yang terakhir - kemampuan untuk menginstal perintah sangat berguna, bahkan jika itu menyebabkan masalah.

Menolak pip demi python -m pip mungkin lebih masuk akal. Saat pip diinstal ke lingkungan Python tempat ia berjalan, masuk akal untuk memperjelas yang mana itu. Tapi itu masih akan kehilangan kenyamanan, dan terobosan besar dalam apa yang biasa dilakukan orang.

Maksud saya secara khusus skrip pembungkus untuk pip itu sendiri. Setuju itu kehilangan kenyamanan, dan saya tidak akan menentang mempertahankannya dalam beberapa bentuk (#3164 menyarankan memiliki proyek pip-cli baru yang hanya memasok pembungkus) tetapi poin utamanya adalah untuk python -m pip menjadi sarana yang didukung untuk menjalankan pip.

Tidak dapat memanggil skrip pembungkus pip yang menunjukkan peringatan jika python saat ini (di PATH atau apa pun yang akan digunakan dengan python -m pip ) bukan python yang digunakan oleh pip ? Mungkin bahkan mendelegasikan ke python -m pip jika dipanggil dengan cara ini?

Demikian pula, pipenv memperingatkan jika pengguna sudah berada di virtualenv, dan jika demikian menggunakan virtualenv itu alih-alih mengelolanya sendiri, setelah mengeluarkan peringatan.

Oke, perhatikan di sini bahwa #7002 telah disetujui oleh 3 dari 6 pengelola pip saat ini.

Itu membuat pip beralih dari instalasi non-pengguna ke instalasi pengguna secara default, dalam banyak kasus di mana kita benar-benar harus melakukan instalasi pengguna. Saya memiliki dua masalah yang lebih luas dengan membuat perubahan ini, yang harus kita pikirkan sebelum membuat rilis yang membuat peningkatan itu.

  • Apakah kami menginginkan mekanisme untuk secara eksplisit memilih keluar dari pemasangan pengguna setelah kami beralih ke sana secara default? Jika demikian, apa bedanya dengan --no-user ? (Saya setuju untuk mengganti nama --no-user menjadi --global sebagai penyisihan eksplisit).
  • Apa strategi "transisi" kita?

    • Bagaimana kita ingin mengkomunikasikan perubahan ini?

    • beri tahu pengguna untuk berhati-hati saat melakukan peningkatan ini?

    • Masalah seperti apa yang kami harapkan akan diangkat oleh pengguna, ketika perubahan ini diterapkan + dirilis?

Saya akan mengatakan --global salah nama jika Anda berada di dalam suatu lingkungan. Untuk flit install , kebalikan dari --user adalah --env , yang secara longgar saya maksudkan untuk memasukkan "lingkungan sistem Python", tetapi saya rasa itu juga tidak sepenuhnya jelas. Mungkin --no-user masih merupakan pilihan terbaik - ini jelas kebalikan dari --user .

Saya pikir --no-user (atau variabel lingkungan yang setara atau entri konfigurasi) harus mengembalikan perilaku yang ada, karena default saat ini secara efektif user = False .

Satu-satunya skenario yang saya buat di mana perubahan akan membingungkan adalah jika Anda berpikir Anda memiliki izin untuk menginstal ke lingkungan (dengan situs pengguna diaktifkan, misalnya conda) padahal sebenarnya tidak: kegagalan lebih jelas daripada melakukan a pengguna menginstal, bahkan jika ada pesan log tentang hal itu. Saya belum memikirkan cara yang baik untuk meningkatkannya.

Mungkin juga deteksi kemampuan menulis bisa salah. Positif palsu hanya memberi Anda perilaku yang ada (coba dan gagal melakukan instalasi normal). Negatif palsu akan melakukan instalasi pengguna ketika itu bisa melakukan yang normal.

Itu membuat pip beralih dari pemasangan non-pengguna ke pemasangan pengguna secara default.

Tidak (misalnya) di Windows, di mana (secara default) instalasi Python adalah instalasi per pengguna dan paket situs dapat ditulisi secara default. Itu adalah sesuatu yang saya sukai secara umum tentang #7002, karena pengalaman saya sejak masalah ini (#1668) dibuka adalah terlalu mudah untuk mengacaukan lingkungan "campuran" di mana Anda memiliki paket seperti pip yang diinstal baik di paket situs dan situs pengguna. Jadi saya sekarang mendukung melakukan instalasi sistem jika memungkinkan, dan hanya melakukan instalasi pengguna dalam kasus-kasus seperti Python yang dikelola sistem Linux, di mana paket situs tidak dapat ditulis.

Setelah mengatakan bahwa:

  1. Sepertinya tidak ada gunanya opsi --no-user , karena #7002 berarti Anda mendapatkan instalasi pengguna hanya jika instalasi sistem tetap gagal.
  2. Hal terbesar yang menurut saya perlu kita komunikasikan mengenai transisi adalah bahwa orang harus sangat berhati-hati dengan banyak pemasangan, dan itu adalah sesuatu yang hanya dapat ditangani dengan pemahaman dan pendidikan pengguna, bukan dengan solusi apa pun di pip. Ini pada dasarnya adalah masalah inti Python. Kami dapat memperluas pip check untuk melaporkan ketika ada situs dan pengguna menginstal sebuah paket dan pengguna yang membayangi situs tersebut, saya kira...

Sepertinya tidak ada gunanya opsi --no-user

Untuk lebih jelasnya, ini sudah ada, meskipun mungkin tidak sering berguna. Jika Anda memiliki user=true dalam file konfigurasi, --no-user harus menggantikannya.

Untuk lebih jelasnya, ini sudah ada

Maaf, saya seharusnya lebih jelas. Saya tidak melihat ada gunanya memiliki "mekanisme untuk secara eksplisit memilih keluar dari pemasangan pengguna setelah kami beralih ke itu secara default", setidaknya dalam arti bahwa saya menganggap maksud @pradyunsg , yaitu tentang memilih keluar dari perilaku #7002, yang tidak sama dengan "beralih ke pemasangan pengguna secara default", seperti yang saya katakan.

Sebenarnya, saya tidak yakin itu lebih jelas ;-) Mungkin yang ingin saya katakan adalah "kita tidak memerlukan opsi lebih dari yang kita miliki saat ini"...

Hmm... @pfmoore Setelah #7002, apa yang diperlukan untuk menyelesaikan masalah ini?

PS: Saya menulis komentar sebelumnya dengan tergesa-gesa dan tidak sengaja diposting. Pelurunya OK; Saya masih menyusun paragraf sebelumnya, ketika sudah diposting. Maaf atas kebingungan yang mungkin terjadi.

@pradyunsg Mengingat bahwa saya sekarang cenderung tidak merasa bahwa --user sebagai default adalah ide yang baik kecuali itu benar-benar diperlukan (kasus #7002 alamat) Saya lebih suka mengatakan bahwa kita dapat mengabaikan masalah ini sebagai bukan lagi ide bagus sekarang setelah #7002 selesai.

Mengambil 2 poin peluru Anda sebagai hal yang mungkin kami perlukan untuk menghitung #7002 sebagai lengkap, komentar saya di atas mencakup itu.

Saya mengikuti catatan rilis di sini.
https://pip.pypa.io/en/stable/news/#id3
"Default untuk melakukan instalasi pengguna (seolah-olah --user diteruskan) ketika direktori paket situs utama tidak dapat ditulisi dan paket situs pengguna diaktifkan. (#1668)"

Bangunan saya sekarang gagal dengan

ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Ini tampaknya diperbaiki dengan menghapus --user dari perintah pip saya.

Apakah ini perilaku yang diharapkan? Catatan rilis tampaknya tidak mencerminkan hal ini.

tautan ke skrip yang sekarang gagal pada pip 20.0.1 (menghapus --user memperbaiki kegagalan yang sulit)
https://github.com/lfit/releng-global-jjb/blob/master/shell/python-tools-install.sh

Jika benar bahwa paket situs pengguna tidak dapat diimpor dari lingkungan itu, maka itu adalah perilaku yang diharapkan, tetapi ortogonal untuk PR ini. Cek itu diperkenalkan bertahun-tahun yang lalu (#567), tetapi sepertinya cek itu rusak dengan venv hingga baru-baru ini (#7155). Ada catatan rilis untuk itu:

Tangani paket situs sistem dengan benar, di lingkungan virtual yang dibuat dengan venv (PEP 405).

Ah ya, terima kasih atas komentar Anda. Saya menemukan ini ...
skrip saya sedang mengisi .local/bin/
saat aku berlari

python3 -m venv ~/.local

dan kemudian di shell login ubuntu (#!/bin/bash -l) .local/bin ditambahkan ke path (jadi memanggil python3 sekarang memanggil .local/bin/python3 executable) Yang tidak kita inginkan.
Saya tidak pernah perlu menjalankan python3 -m venv ~/.local
atau panggil skrip saya dari shell login, dan menghapus kedua atau salah satu dari masalah ini akan memperbaikinya.

#fresh ubuntu docker
root<strong i="13">@7d8107816f64</strong>:/# python3 -m pip install  --user --upgrade pip
Successfully installed pip-20.0.1
root<strong i="14">@7d8107816f64</strong>:/# python3 -m pip --version
pip 20.0.1 from /root/.local/lib/python3.6/site-packages/pip (python 3.6)
root<strong i="15">@7d8107816f64</strong>:/# ls root/.local/bin/pip
pip     pip3    pip3.6
#Now we populate ~/.local/bin/
root<strong i="16">@7d8107816f64</strong>:/# python3 -m venv ~/.local
root<strong i="17">@7d8107816f64</strong>:/# ls root/.local/bin/
activate          activate.fish     easy_install-3.6  pip3              python
activate.csh      easy_install      pip               pip3.6            python3
root<strong i="18">@7d8107816f64</strong>:/# ./root/.local/bin/python --version
Python 3.6.9
root<strong i="19">@7d8107816f64</strong>:/# ./root/.local/bin/python -m pip install  --user --upgrade pip
ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Jadi jika kita menjalankan .local/bin/python yang dapat dieksekusi, kita tidak dapat menginstal pip dengan --user

Oh, saya melewatkan apa yang Anda lakukan python3 -m venv ~/.local . Itu mungkin membingungkan alat seperti pip, karena ~/.local adalah awalan untuk instalasi --user (di Linux). venvs dan --user adalah dua cara _berbeda_ Anda dapat menginstal paket tanpa membuat perubahan di seluruh sistem: Anda harus menggunakan satu atau yang lain. Membuat venv di ~/.local membuat beberapa hibrida aneh dari keduanya.

Perilaku baru mungkin nyaman bagi banyak orang, tetapi pemasangan 'pengguna' telah membuat saya sedih sebagai pengembang web - saya sering perlu menyiapkan virtualenvs yang akan digunakan ke mesin produksi kami, dan jika ada paket yang diinstal di perpustakaan pengguna saya, kemudian secara default pip akan menolak untuk menginstalnya ke virtualenv yang saya siapkan, dan masih akan keluar dengan sukses . Pemberitahuan bahwa diputuskan untuk tidak menginstal paket terkubur di dalam 30 atau 40 halaman keluaran dari skrip yang saya gunakan untuk menyiapkan virtualenv. Efek akhirnya adalah setelah virtualenv di-deploy, paket-paket dari direktori home saya tidak lagi tersedia, jadi beberapa paket acak hilang dari aplikasi web produksi saya, dan gagal total.

Saya bersedia mengakui bahwa kasus penggunaan saya bukan yang khas, jadi mungkin ini masih merupakan ide yang bagus dari sudut pandang kegunaan umum.

Untuk orang lain yang memiliki masalah serupa, ada beberapa cara untuk mengatasinya:

  • Tambahkan --force-reinstall ke semua baris perintah pip install Anda dalam skrip, dll
  • Hapus ~/.local/lib/python* dan edit ~/.pip/pip.conf untuk menambahkan user = no di bagian global :
[global]
user = no
  • Lakukan sesuatu yang lebih drastis, seperti mengubah ~/.local/lib menjadi file daripada direktori :smirk:

Seperti biasa, pengelola pengemasan yang terhormat, terima kasih atas semua yang Anda lakukan - saya yakin hampir tidak mungkin mengubah apa pun tanpa merusak barang seseorang, dan fakta bahwa Anda tetap menempa sebenarnya bagus, karena memungkinkan kami membuat kemajuan.

Ah, penginstalan pengguna juga dapat menyebabkan masalah besar dalam lingkungan integrasi berkelanjutan, di mana banyak hal berbeda dijalankan sebagai akun pengguna yang sama, tetapi orang masih mengharapkan build untuk diisolasi satu sama lain. Kami memecahkan ini dengan membuat ~/.local read-only, tetapi solusi di atas mungkin juga akan berfungsi.

Saat Anda membuat virtualenv dengan opsi default, itu terisolasi: ia tidak dapat melihat paket situs pengguna atau sistem Anda, dan akibatnya pip seharusnya hanya berfungsi dengan paket yang diinstal di env. Ini menjadi default bertahun-tahun yang lalu, karena jenis masalah yang Anda gambarkan.

Jika Anda membuat virtualenvs dengan opsi --system-site-packages (atau versi virtualenv yang sangat lama di mana itu adalah default), mereka bertindak sebagai overlay pada paket yang seharusnya Anda instal, baik di seluruh sistem dan di rumah Anda direktori. Jika Anda ingin agar paket sistem terlihat tetapi bukan paket pengguna, Anda dapat menjalankan Python dengan opsi -s atau variabel lingkungan PYTHONNOUSERSITE .

Oh! Saya sangat menyesal, Anda benar sekali. Kebijakan paket-situs-sistem organisasi saya yang aneh menyerang lagi. Terima kasih telah menunjukkan beberapa solusi.

Tidak masalah. Paket situs sistem lebih umum beberapa tahun yang lalu ketika kami sering mengandalkan manajer paket sistem untuk hal-hal seperti numpy, jadi mungkin ada baiknya meninjau kembali kebijakan itu. Tapi mungkin masih ada alasan yang masuk akal untuk menggunakannya hari ini.

Penutupan sejalan dengan https://github.com/pypa/pip/issues/1668#issuecomment -544569965.

Terima kasih banyak @takluyver! ^>^

@takluyver Terima kasih telah menyelesaikan masalah yang telah lama mengganggu saya
Tetapi saya perhatikan bahwa ketika menginstal paket dengan pengguna yang tidak memiliki hak istimewa, Windows 10 python 3.8.2 dengan pip 20.0.2 masih gagal.

ERROR: Exception:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\cli\base_command.py", line 186, in _main
    status = self.run(options, args)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 253, in run
    options.use_user_site = decide_user_install(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 604, in decide_user_install
    if site_packages_writable(root=root_path, isolated=isolated_mode):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 548, in site_packages_writable
    return all(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 549, in <genexpr>
    test_writable_dir(d) for d in set(get_lib_location_guesses(**kwargs))
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 140, in test_writable_dir
    return _test_writable_dir_win(path)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 153, in _test_writable_dir_win
    fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL)
PermissionError: [Errno 13] Permission denied: 'c:\\program files (x86)\\python38-32\\Lib\\site-packages\\accesstest_deleteme_fishfingers_custard_m59lch'

Saya pikir ini dapat disebabkan oleh OSError 's errno menjadi errno.EACCES tetapi errno.EPERM .

@catPill tolong buka edisi baru agar bisa terlacak dengan baik. Sangat masuk akal bahwa saya melewatkan sesuatu di Windows.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat