Cum se face că în anul 2025 al Domnului nostru instalarea unui pachet Python este încă un astfel de joc?
Această postare provine de la cineva care folosește rar Python, dar ia în considerare următoarele:
- Cele mai rare momente pe care trebuie să o folosesc, de multe ori mă confrunt cu dependența de iad (și dacă credeți că este o problemă de îndemânare, țineți acest gând și continuați să citiți);
- Sunt unul dintre întreținătorii ecosistemului R pentru NIX, dar, de asemenea, ambalează unele pachete Python din când în când pentru NIX.
Acest ultim punct este destul de important, ceea ce cred că îmi oferă o perspectivă bună asupra problemei despre care este vorba despre această postare pe blog. Când vine vorba de pachete R, știm că putem pur și simplu să oglindăm CRAN și Bioconductor, întrucât echipa CRAN din amonte a făcut deja o mulțime de eforturi de curat: știm că pachetele lucrează între ele. Cu toate acestea, nu se poate face același lucru pentru Python: Curația este asupra noastră.
Dacă utilizați Python pentru a analiza datele (îmi pare rău pentru dvs.), probabil că ați lovit această problemă: instalați un pachet care necesită numpy < 2și altul care necesită numpy >= 2. Ești gătitașa cum spun tinerii. Rezolvarea nu vă poate ajuta, deoarece cerințele sunt literalmente incompatibile. Nimeni nu te poate ajuta. Nici o cantitate de manageri de pachete scrise de rugină nu vă poate ajuta. Problema este pypi.
Cran nu tolerează această prostie
În R, această situație pur și simplu nu se întâmplă. De ce? Deoarece CRAN aplică un sistem în care pachetele sunt testate nu numai în mod izolat, ci și împotriva dependențelor lor inversă. Dacă {ggplot2} sau {dplyr} Schimbări într -un mod care îi rupe pe alții, Cran o prinde. Autorii pachetului primesc un avertisment și, dacă nu remediază lucrurile (în termen de 2 săptămâni!), Pachetul lor este arhivat, ceea ce înseamnă că atunci când utilizatorii încearcă să -l instaleze install.packages("foo")nu va funcționa. Ceea ce înseamnă că dacă un pachet este pe Cran, install.packages("foo") va funcționa. Nu „funcționează dacă ai noroc”. Nu „funcționează dacă fixați versiunile potrivite.” Doar funcționează (desigur, atâta timp cât sunt disponibile dependențele potrivite la nivel de sistem dacă aveți nevoie să îl compilați, ceea ce nu este o problemă dacă instalați binare). De fapt, nu puteți publica nici măcar un pachet care are constrângeri asupra versiunii dependențelor sale. Pachetul dvs. trebuie să funcționeze cu toate pachetele de pe CRAN pentru totdeauna. Sincer, destul de impresionant pentru ceva care nu este chiar un limbaj de programare real, nu? (acesta este sarcastic btw)
Iar Cran gestionează această consecvență 27000 de pachete. PYPI este mult mai mare, acordat, dar mă îndoiesc că multe mai mult de 30 de pachete se folosesc de fapt frecvent. De fapt, probabil câteva mii, poate chiar și câteva sute (în special pentru analiza datelor).
PYPI este un depozit, nu un ecosistem
PYPI nu face acest lucru. Este un teren de dumping pentru tarbaluri și roți. Fără verificări globale, fără garanții de compatibilitate, fără consecvență între ecosistem. Dacă pachetul A și pachetul B declară cerințe reciproc exclusiv, PYPI ridică din umeri și le găzduiește pe amândouă.
Apoi cheltuim instrumente enorme de eforturi pentru a încerca să tratăm această mizerie: Condic, Poezie, Hatch, UV, Pipx și Nix (bine Nix nu a fost realizat special pentru Python, dar poate fi folosit și pentru a configura medii virtuale). Toate sunt instrumente grozave, dar nu pot rezolva problema de bază: dacă constrângerile în sine sunt imposibile, niciun rezolutor nu vă poate salva. În cel mai bun caz, aceste instrumente vă oferă o modalitate de a îngheța o mizerie de lucru înainte de a se prăbuși. Rugați -vă la orice zeitate pe care o place că adăugarea unui nou pachet pe linie nu vă explodează mediul.
Acesta nu este un ecosistem. Este haos cu instrumente de ambalare bune.
Dar Nix ajută un pic mai mult; Cel puțin cu NIX, puteți plasa un pachet pyproject.toml să încerc să relaxez dependențele imocompatibile, așa cum am făcut -o eu saiph:
postPatch=""
# Remove these constraints
substituteInPlace pyproject.toml \
--replace 'numpy = "^1"' 'numpy = ">=1"' \
--replace 'msgspec = "^0.18.5"' 'msgspec = ">=0.18.5"'
'';
Acest pas a relaxat constrângerile direct în pyproject.tomldar s -ar putea să nu fie o idee bună: aceste constrângeri ar fi putut fi acolo dintr -un motiv întemeiat. Totuși, testele unitare au trecut (mai mult de 150 dintre ele), așa că în acest caz particular cred că sunt bun. Dacă PYPI a fost gestionat ca Cran, saiphAutorii ar fi avut 2 săptămâni pentru a se asigura că saiph A funcționat bine cu Numpy 2, ceea ce pare a fi cazul aici. Dar pachetele de patching nu este cu siguranță o soluție pentru toate.
Mitul scării
„Dar Python este prea mare și divers pentru guvernarea în stil Cran!” Te aud strigând. Acest lucru este pur și simplu fals. CRAN gestionează 27000 de pachete pe domenii la fel de variate precum bioinformatica, finanțele, răzuirea web, analiza geospatială și învățarea automată, iar acest lucru este fără a număra pachete vechi care au fost arhivate de -a lungul anilor. Ecosistemul R nu este mic sau omogen. Este mai mic decât PYPI în numere absolute, da, dar sincer, mă îndoiesc că există mai multe pachete de analiză a datelor pe PYPI decât pe CRAN, iar dacă pachetele Python mai vechi ar fi eliminate, numărul de pachete PYPI ar fi, de asemenea, mult mai mic. Dacă cineva are statistici grele în acest sens, aș fi fericit să le citesc.
Diferența nu este capacitatea tehnică sau dimensiunea ecosistemului. Sale Filosofia guvernanței. Cran a ales consecvența peste permisivitate. PYPI a ales contrariul.
Și nu, conda-Forge nu este suficient
Condic-Forge este curat prin faptul că construcțiile sale sunt consecvente, compilatoarele sunt fixate, migrațiile sunt coordonate. Este minunat și se dovedește că ambalajele Python poate funcționa la scară.
Dar dacă pachetul A dorește numpy < 2 și pachetul B vrea numpy >= 2Conda-Forge le va găzdui pe amândouă și ești încă blocat. Nu există niciun mecanism de aplicare care să obligă ecosistemul să rezolve contradicțiile. Cran are asta. Conda-Forge nu.
Conda-Forge este un pas în direcția corectă, dar este necesară o guvernare mai strânsă.
Ce are de fapt Python: Pypan
Python are nevoie de un strat curat deasupra PYPI care să aplice consecvența. Numiți -l Pypan: rețeaua de arhivă a pachetului Python.
Iată ce ar face Pypan:
- Pachete de oglindă de la PYPI, dar numai cele care trec de verificări la nivelul întregii ecosistem
- Testați fiecare pachet împotriva dependențelor sale inverse, nu doar în sine
- Coordonează migrațiile pentru schimbări majore de rupere (de exemplu,
numpy 2.0) - Pachete de arhivă care refuză să se adapteze
- Publicați instantanee consecvente și instalate ale întregului ecosistem
Cu alte cuvinte: Cran, dar pentru Python.
Dacă CRAN poate menține consecvența pe 27000 de pachete (de către o echipă atât de mică, apropo), Python poate. Întrebarea nu este dacă este posibil din punct de vedere tehnic, dar dacă comunitatea Python este dispusă să acorde prioritate stabilității ecosistemului față de autonomia individuală a pachetului.
De ce dezvoltatorii s -ar supune lui Pypan
De ce s -ar deranja un autor al pachetului? Simplu:
- Vizibilitate: utilizatorii vor prefera pachetele de pe Pypan, deoarece se instalează și lucrează efectiv
- Mai puțină sarcină de sprijin: mai puține rapoarte de erori despre instalări rupte sau dependență iad
- Responsabilitatea împărtășită: Efortul de migrare s -a răspândit pe ecosistem, nu a fost lăsat la întreținători individuali
- Credibilitate: „Pe Pypan” devine o marcă de calitate și stabilitate – în special pentru proiectele științifice și din industrie
Poate să începem mic
Modelul lui Cran dovedește că consistența la nivelul ecosistemului este realizabilă și sunt de părere că ar putea fi realizabilă și la scara lui Python. Conda-Forge dovedește că ambalajele curate Python funcționează.
Până când Python are ceva de genul Pypan, nimic nu se schimbă. Dependența Iadul va menține dezvoltatorii noaptea.
Dar am putea începe mic. Pypan ar putea începe prin a se concentra pe pachetele de știință a datelor, analize și statistici – ecosistemul principal Python științific. Acest subset este:
- Mai ușor de gestionat: ~ 500-1000 de pachete (am alcătuit acest interval, ar putea fi mai mult ar putea fi mai puțin, punctul este că nu sunt cele 300000 de pachete PYPI) în loc de întregul PYPI
- Extrem de interconectat: Numpy, Pandas, Scikit-Learn, Matplotlib, Scipy formează un grafic de dependență naturală
- Axat pe stabilitate: Oamenii de știință de date prioritizează rezultatele reproductibile asupra caracteristicilor de sângerare
- Comunitate: Python științific coordonează deja migrațiile majore (Python 2 → 3, Numpy 2.0)
- Cerere dovedită: Acești utilizatori gravitează deja spre Conda-Forge pentru stabilitate
Un pypan-ds (știința datelor) ar putea demonstra lucrările modelului, ar putea crea încredere și ar putea crea un impuls pentru adoptarea mai largă. Odată ce oamenii văd asta pip install pandas (sau uv dacă preferați) poate funcționa la fel de fiabil ca install.packages('dplyr')extinderea la cadre web și alte domenii devine mult mai ușor de vândut.
Comunitatea științifică Python are coeziunea, nevoia și precedentul pentru acest tip de coordonare. Ar putea fi programul pilot CRAN al lui Python.
Soooo … cine construiește asta?

