2015-02-13 22 views
7

Mam zamiar wydać bibliotekę Pythona, nad którą pracowałem przez ostatnie kilka tygodni. Czytałem dużo o zależnościach Pythona, ale coś jeszcze nie jest do końca jasne:Czy powinienem przypiąć moje wersje zależności Pythona?

Niektórzy ludzie udają, że powinieneś nigdy nie dopinać do swoich wersji zależności, ponieważ mogłoby to uniemożliwić użytkownikom twojej biblioteki uaktualnienie tych zależności.

Niektóre inne twierdzenie, że należy zawsze przypiąć swoje wersje zależnościami, ponieważ jest to jedyny sposób zagwarantowania, że ​​uwolnienie działa tak, jak to miało miejsce, gdy rozwinął go i aby zapobiec, że łamanie zmiana w zależności sieje spustoszenie w twoja biblioteka.

ja jakoś poszło za rozwiązanie hybrydowe, gdzie zakłada moi zależności wykorzystywane semantic versioning i przypięty tylko główny numer wersji (słownie somelib >= 2.3.0, < 3), z wyjątkiem, gdy główny numer wersji jest 0 (semantyczny wersjonowanie podpowiada, że ​​takie wersje mają być uważane za niestabilne i może przerwać działanie API, nawet jeśli natknie się tylko na numer poprawki).

Odtąd nie jestem pewien, która droga jest najlepsza. Czy istnieje oficjalna wytyczna (może nawet PEP?), Która dyktuje najlepszą praktykę dotyczącą zależności Pythona i jak je określać?

+0

Dobre pytanie. Myślę, że to powinno być adresowane przez społeczność Pythona. – pylang

Odpowiedz

-2

Powinieneś zawsze przypinać swoje zależności, ponieważ zwiększa to możliwość bezpiecznych, powtarzalnych buildów, nawet z upływem czasu. Wersje przypięte stanowią deklarację opiekuna pakietu, który potwierdził, że Twój kod działa w danym środowisku. Ma to pozytywny efekt uboczny zachowania zdrowia psychicznego, ponieważ nie będziesz zalewany raportami błędów, w których musisz zagrać inspektora w każdą współzależność pakietu i szczegóły systemu.

Użytkownicy zawsze mogą zignorować zależne wersje wersji i zrobić to na własne ryzyko. Jednak po wydaniu nowych wersji biblioteki należy zaktualizować wersje zależności, aby wprowadzić ulepszenia i poprawki błędów.

Odcinek PEP 426 about Semantic dependencies (metadane dla pakietów Python Software) stwierdza:

„Zarządzanie Zależność jest silnie uzależniona od systemu identyfikacji i wersja specyfikacji określonej w PEP 440 (PEP 440 - wersja Identyfikacji i zależności od wyposażenia).”

Z tego wnioskuję, że autorytatywna "najlepsza praktyka" polega na zmianie twoich zależności, ponieważ relacja PEP na opakowaniu jest określona jako "silnie zależna" od szczegółów wersyfikacji nakreślonych przez powiązaną PEP.

+0

Twoje wnioskowanie z ostatniego akapitu jest nieprawidłowe. Cytat oznacza, że ​​aby zarządzanie zależnościami działało poprawnie, pakiety muszą używać semantycznych numerów wersji, które są zgodne z formatem określonym przez PEP. Nie ma to nic wspólnego z tym, jak należy określać ścisłe lub luźne zależności. – augurar

+1

Badanie w [Python Dependency Resolution] (https://docs.google.com/document/d/1x_VrNtXCup75qA3glDd2fQOB2TakldwjKZ6pXaAjAfg/) zwraca uwagę na szereg problemów związanych z przypinaniem, co udokumentowano w mojej odpowiedzi. – nealmcb

+0

"Wersje przypięte stanowią deklarację opiekuna pakietu, który potwierdził, że Twój kod działa w danym środowisku." - To prawda, ale problem polega na tym, że można podpisać tylko jedną * taką deklarację przy łączeniu zależności z bardzo konkretnymi wersjami, podczas gdy w rzeczywistości inne wersje mogą działać równie dobrze (a być może nawet to zweryfikowałeś). – stakx

3

Przypinanie może być problematyczne i prowadzić do zagrożeń bezpieczeństwa. Szczególnie w przypadku biblioteki, tak jak w twoim przypadku, może to prowadzić do konfliktów zależności, jeśli będzie zazwyczaj używana w połączeniu z innymi pakietami PyPI, które same będą miały zależności.

Dlaczego? Szczegółowe badanie Python Dependency Resolution, po przeanalizowaniu dziesiątek tysięcy pakietów PyPI i ich aktualnych konfliktów zależności, omawia tę kwestię. Wyjaśnia on, że:

jeśli dystrybucja nie jest zainstalowany na własnym, pustym, środowiska jednofunkcyjnych, wówczas prawdopodobieństwo konfliktów zależność jest znacznie zwiększona, jeżeli wersje zależnościami są przypięte zamiast pozostawienia zakresy elastyczne.

i zauważa, że ​​Przypinanie może zaostrzyć problemy związane z bezpieczeństwem poprzez zakłócanie modernizacji.

Doradza:

Jeśli projekt szpilki zależności, to musi być przygotowany do wydania nowej wersji za każdym razem jest ważnym wydanie czegokolwiek projekt zależy bezpośrednio lub pośrednio, przez całą drogę w dół łańcuch zależności.

6

Powód, dla którego dwie pozostałe odpowiedzi są sprzeczne, jest taki, że oba są prawidłowe (i warte przeczytania), ale mają zastosowanie w różnych sytuacjach.

Jeśli zwalniasz bibliotekę w PyPI, powinieneś zadeklarować wszystkie zależności, które znasz, ale nie pin do konkretnej wersji. Na przykład, jeśli wiesz, że potrzebujesz >= 1.2, ale 1.4 jest zepsuty, możesz napisać coś w stylu: somepkg >= 1.2, != 1.4. Jeśli wiesz, że somepkg następuje po SemVer, możesz dodać < 2.

Jeśli budujesz coś takiego jak aplikacja internetowa, którą sam instalujesz, powinieneś przypiąć wszystkie swoje dokładne zależności i użyć usługi takiej jak pyup.io lub require.io, aby powiadomić Cię o wydaniu nowych wersji. W ten sposób możesz być na bieżąco, upewniając się, że wdrażane wersje są takie same, jak wersje testowane.

Zauważ, że te dwie porady uzupełniają się nawzajem: to tylko fakt, że jeśli aplikacja A używa biblioteki B, to autor A lub autor B może przypisać zależności B, ale nie obie. Musimy więc wybrać jedną. Podstawową zasadą jest to, że najlepiej jest zrobić to tak późno, jak to możliwe, tj. Przez autora A, który widzi cały ich system; zadaniem biblioteki B jest przekazanie kilku przydatnych wskazówek, które pomogą A podjąć te decyzje. W szczególności, jeśli wszystkie biblioteki A zależą od tego, co dokładnie wiedzą o swoich podstawowych zależnościach, A może rozsądnie podejmować decyzje o tym, co zrobić, gdy się nakładają. Podobnie jak w przypadku zależności B od requests >= 1.0, != 1.2, a zależność C zależy od requests >= 1.1, to możemy zgadnąć, że 1.1 lub 1.3 mogą być dobrymi wersjami do przypięcia. Jeśli zależność B zależy od requests == 1.1, a zależność C zależy od requests == 1.2, to po prostu utknęliśmy.

+0

To bardzo klarowne wyjaśnienie, które stawia pozostałe dwie odpowiedzi we właściwej perspektywie. I rada jest prawdopodobnie dobra nie tylko dla pakietów Pythona, ale wszelkiego rodzaju zarządzania pakietami, które podąża za czymś takim jak semver. Z łatwością zasługuje na zaakceptowaną odpowiedź, IMO. – stakx