Использование 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
является сторонней утилитой, но используется программой setuptools (так что вы, вероятно, уже установили ее) и соответствует текущей PEP 440 ; он вернет, packaging.version.Version
если версия соответствует, и packaging.version.LegacyVersion
если нет. Последний всегда будет сортировать перед верными версиями.
Примечание : упаковка была недавно продана в setuptools .
Древняя альтернатива, все еще используемая многими программами distutils.version
, встроена, но не документирована и соответствует только замененному 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'
Как вы можете видеть, он считает действительные версии PEP 440 «не строгими» и поэтому не соответствует представлениям современного Python о том, что такое действительная версия.
Как distutils.version
это недокументировано, вот соответствующие строки документации.
distutils.version
без документов.version.py
исходный код. Очень красиво положено!packaging.version.parse
нельзя доверять для сравнения версий. Попробуйте,parse('1.0.1-beta.1') > parse('1.0.0')
например.Библиотека упаковки содержит утилиты для работы с версиями и другие функции, связанные с упаковкой. Это реализует PEP 0440 - Идентификация версии, а также может анализировать версии, которые не соответствуют PEP. Он используется pip и другими распространенными инструментами Python для анализа и сравнения версий.
Это было отделено от исходного кода в setuptools и pkg_resources, чтобы обеспечить более легкий и быстрый пакет.
До появления библиотеки упаковки эта функциональность была (и все еще может быть) найдена в пакете pkg_resources, предоставляемом setuptools. Однако это больше не является предпочтительным, так как больше не гарантируется установка setuptools (существуют другие инструменты упаковки), и pkg_resources по иронии судьбы использует довольно много ресурсов при импорте. Тем не менее, все документы и обсуждения по-прежнему актуальны.
Из
parse_version()
документов :Указанный «оригинальный алгоритм» был определен в более старых версиях документов, до появления PEP 440.
Документации приведены некоторые примеры:
источник
источник
map()
функцию целиком, как результатsplit()
это уже строки. Но вы все равно не хотите этого делать, потому что причина их изменения вint
том, чтобы они правильно сравнивались как числа. В противном случае"10" < "2"
.versiontuple("1.0") > versiontuple("1")
. Версии одинаковые, но кортежи созданы(1,)!=(1,0)
distutils.version.LooseVersion
. Вот для чего это.Что плохого в преобразовании строки версии в кортеж и оттуда? Кажется достаточно элегантным для меня
Решение @ kindall - быстрый пример того, как хорошо будет выглядеть код.
источник
setuptools
которогоpkg_resources
.pkg_resources
, и что предположения о простом именовании пакетов не всегда могут быть идеальными.sys.version_info > (3, 6)
или что-то еще.Существует упаковка пакет , доступный, который позволит вам сравнить версии в соответствии с PEP-440 , а также устаревшие версии.
Поддержка устаревшей версии:
Сравнение устаревшей версии с версией PEP-440.
источник
packaging.version.Version
иpackaging.version.parse
: «[version.parse
] берет строку версии и будет анализировать ее как,Version
если версия является действительной версией PEP 440, в противном случае она будет анализироваться какLegacyVersion
». (тогда какversion.Version
подниметInvalidVersion
; источник )Вы можете использовать пакет semver , чтобы определить, удовлетворяет ли версия семантической версии требованиям . Это не то же самое, что сравнение двух реальных версий, но это тип сравнения.
Например, версия 3.6.0 + 1234 должна совпадать с 3.6.0.
источник
Публикация моей полной функции на основе решения Kindall. Я мог поддерживать любые буквенно-цифровые символы, смешанные с числами, добавляя в каждую версию раздела начальные нули.
Хотя он, конечно, не так хорош, как его однострочная функция, он, похоже, хорошо работает с буквенно-цифровыми номерами версий. (Просто убедитесь, что установили
zfill(#)
значение соответствующим образом, если в вашей системе управления версиями есть длинные строки.),
источник
То, как это
setuptools
делается, используетpkg_resources.parse_version
функцию. Это должен быть PEP440 совместимым.Пример:
источник
pkg_resources
является частью, отsetuptools
которой зависитpackaging
. Смотрите другие ответы, которые обсуждаютpackaging.version.parse
, который имеет аналогичную реализацию дляpkg_resources.parse_version
.Я искал решение, которое не добавило бы никаких новых зависимостей. Проверьте следующее (Python 3) решение:
РЕДАКТИРОВАТЬ: добавлен вариант со сравнением кортежей. Конечно, вариант со сравнением кортежей лучше, но я искал вариант со сравнением целых чисел
источник