Zastosowanie packaging.version.parse
.
>>> from packaging import version
>>> version.parse("2.3.1") < version.parse("10.1.2")
True
>>> version.parse("1.3.a4") < version.parse("10.1.2")
True
>>> isinstance(version.parse("1.3.a4"), version.Version)
True
>>> isinstance(version.parse("1.3.xy123"), version.LegacyVersion)
True
>>> version.Version("1.3.xy123")
Traceback (most recent call last):
...
packaging.version.InvalidVersion: Invalid version: '1.3.xy123'
packaging.version.parse
jest narzędziem innej firmy, ale jest używane przez setuptools (więc prawdopodobnie już go masz) i jest zgodne z obecnym PEP 440 ; zwróci a, packaging.version.Version
jeśli wersja jest zgodna, a packaging.version.LegacyVersion
jeśli nie. Te ostatnie zawsze będą sortować przed ważnymi wersjami.
Uwaga : opakowanie zostało ostatnio sprzedane w setuptools .
Starożytna alternatywa wciąż używana przez wiele programów jest distutils.version
wbudowana, ale nieudokumentowana i zgodna tylko z zastąpionym PEP 386 ;
>>> from distutils.version import LooseVersion, StrictVersion
>>> LooseVersion("2.3.1") < LooseVersion("10.1.2")
True
>>> StrictVersion("2.3.1") < StrictVersion("10.1.2")
True
>>> StrictVersion("1.3.a4")
Traceback (most recent call last):
...
ValueError: invalid version number '1.3.a4'
Jak widać, widzi prawidłowe wersje PEP 440 jako „nie ścisłe”, a zatem nie pasuje do współczesnego rozumienia Pythona co do prawidłowej wersji.
Jak distutils.version
nieudokumentowane, oto odpowiednie dokumenty.
distutils.version
jest nieudokumentowane.version.py
kod źródłowy. Bardzo ładnie ułożone!packaging.version.parse
nie można ufać porównać wersje. Spróbujparse('1.0.1-beta.1') > parse('1.0.0')
na przykład.Pakowanie biblioteka zawiera narzędzia do pracy z wersjami oraz inne funkcje związane z opakowań. To implementuje PEP 0440 - Identyfikacja wersji, a także może analizować wersje, które nie są zgodne z PEP. Jest używany przez pip i inne popularne narzędzia Pythona do analizowania wersji i porównywania.
Zostało to oddzielone od oryginalnego kodu w setuptools i pkg_resources, aby zapewnić lżejszy i szybszy pakiet.
Zanim istniała biblioteka pakietów, ta funkcjonalność została (i nadal może być) znaleziona w pkg_resources, pakiecie dostarczanym przez setuptools. Jednak nie jest to już preferowane, ponieważ nie można już zagwarantować, że setuptools zostanie zainstalowany (istnieją inne narzędzia do pakowania), a pkg_resources ironicznie zużywa sporo zasobów podczas importowania. Jednak wszystkie dokumenty i dyskusje są nadal aktualne.
Z
parse_version()
dokumentów :Wspomniany „oryginalny algorytm” został zdefiniowany w starszych wersjach dokumentów, zanim istniał PEP 440.
Dokumentacja podaje kilka przykładów:
źródło
źródło
map()
całkowicie usunąć funkcję, ponieważ wyniksplit()
jest już ciągiem. Ale i tak nie chcesz tego robić, ponieważ jedynym powodem, aby je zmienić,int
jest prawidłowe porównywanie liczb. Inaczej"10" < "2"
.versiontuple("1.0") > versiontuple("1")
. Wersje są takie same, ale utworzone krotki(1,)!=(1,0)
distutils.version.LooseVersion
Co jest złego w przekształcaniu ciągu wersji w krotkę i stamtąd? Wydaje mi się wystarczająco elegancki
Rozwiązanie @ kindall to szybki przykład tego, jak dobrze wyglądałby kod.
źródło
setuptools
, co jestpkg_resources
.pkg_resources
i że założenia dotyczące prostego nazewnictwa pakietów nie zawsze są idealne.sys.version_info > (3, 6)
czy cokolwiek.Dostępny jest pakiet opakowań , który pozwoli ci porównać wersje zgodnie z PEP-440 , a także wersje starsze.
Obsługa starszych wersji:
Porównanie starszej wersji z wersją PEP-440.
źródło
packaging.version.Version
apackaging.version.parse
„[version.parse
] bierze ciąg wersji i parsuje go tak,Version
jakby wersja była prawidłową wersją PEP 440, w przeciwnym razie parsuje go jakoLegacyVersion
.” (mając na uwadzeversion.Version
, że powstanieInvalidVersion
; źródło )Możesz użyć pakietu semver , aby ustalić, czy wersja spełnia wymagania wersji semantycznej . Nie jest to to samo, co porównywanie dwóch rzeczywistych wersji, ale jest rodzajem porównania.
Na przykład wersja 3.6.0 + 1234 powinna być taka sama jak wersja 3.6.0.
źródło
Publikowanie mojej pełnej funkcji opartej na rozwiązaniu Kindall. Byłem w stanie obsłużyć dowolne znaki alfanumeryczne pomieszane z liczbami, wypełniając każdą sekcję wersji wiodącymi zerami.
Chociaż z pewnością nie jest tak ładna, jak jego funkcja jednowarstwowa, wydaje się, że dobrze współpracuje z alfanumerycznymi numerami wersji. (Pamiętaj tylko, aby odpowiednio ustawić
zfill(#)
wartość, jeśli masz długie ciągi w systemie kontroli wersji.).
źródło
Sposób, w jaki to
setuptools
robi, wykorzystujepkg_resources.parse_version
funkcję. Powinien być zgodny z PEP440 .Przykład:
źródło
pkg_resources
jest częściąsetuptools
, która zależy odpackaging
. Zobacz inne omawiane odpowiedzipackaging.version.parse
, które mają identyczną implementację jakpkg_resources.parse_version
.Szukałem rozwiązania, które nie dodałoby żadnych nowych zależności. Sprawdź następujące rozwiązanie (Python 3):
EDYCJA: dodano wariant z porównaniem krotek. Oczywiście wariant z porównywaniem krotek jest ładniejszy, ale szukałem wariantu z porównaniem liczb całkowitych
źródło