Uso 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
es una utilidad de terceros pero es utilizada por setuptools (por lo que probablemente ya lo tenga instalado) y cumple con el PEP 440 actual ; devolverá a packaging.version.Version
si la versión es compatible y a packaging.version.LegacyVersion
si no. Este último siempre se ordenará antes que las versiones válidas.
Nota : el paquete se ha enviado recientemente a las herramientas de configuración .
Una alternativa antigua aún utilizada por una gran cantidad de software es distutils.version
, incorporada pero no documentada y conforme solo a la PEP 386 reemplazada ;
>>> 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'
Como puede ver, ve versiones válidas de PEP 440 como "no estrictas" y, por lo tanto, no coincide con la noción moderna de Python de lo que es una versión válida.
Como distutils.version
no está documentado, aquí están las cadenas de documentos relevantes.
distutils.version
indocumentada.version.py
código fuente. Muy bien puesto!packaging.version.parse
, no se puede confiar para comparar las versiones. Pruebaparse('1.0.1-beta.1') > parse('1.0.0')
por ejemplo.La biblioteca de empaque contiene utilidades para trabajar con versiones y otras funcionalidades relacionadas con el empaque. Esto implementa PEP 0440 - Identificación de versión y también es capaz de analizar versiones que no siguen la PEP. Lo utiliza pip y otras herramientas comunes de Python para proporcionar análisis y comparación de versiones.
Esto se separó del código original en setuptools y pkg_resources para proporcionar un paquete más ligero y rápido.
Antes de que existiera la biblioteca de empaquetado, esta funcionalidad se encontraba (y aún se puede encontrar) en pkg_resources, un paquete proporcionado por setuptools. Sin embargo, esto ya no se prefiere ya que ya no se garantiza la instalación de las herramientas de configuración (existen otras herramientas de empaque) y, irónicamente, pkg_resources utiliza muchos recursos cuando se importa. Sin embargo, todos los documentos y la discusión siguen siendo relevantes.
De los
parse_version()
documentos :El "algoritmo original" al que se hace referencia se definió en versiones anteriores de los documentos, antes de que existiera PEP 440.
La documentación proporciona algunos ejemplos:
fuente
fuente
map()
función por completo, ya que el resultado yasplit()
es cadenas. Pero de todos modos no desea hacer eso, porque la razón completa para cambiarlos es para que se comparen correctamente como números. De lo contrario .int
"10" < "2"
versiontuple("1.0") > versiontuple("1")
. Las versiones son las mismas, pero las tuplas creadas(1,)!=(1,0)
distutils.version.LooseVersion
. Para eso está ahí.¿Qué hay de malo en transformar la cadena de versión en una tupla e ir desde allí? Parece lo suficientemente elegante para mi
La solución de @ kindall es un ejemplo rápido de lo bien que se vería el código.
fuente
setuptools
, que espkg_resources
.pkg_resources
, y que los supuestos de simple denominación de paquetes pueden no ser siempre ideales.sys.version_info > (3, 6)
o lo que sea.Hay un paquete de empaque disponible, que le permitirá comparar versiones según PEP-440 , así como versiones heredadas.
Soporte de versiones heredadas:
Comparación de la versión heredada con la versión PEP-440.
fuente
packaging.version.Version
ypackaging.version.parse
: "[version.parse
] toma una cadena de versión y la analizará comoVersion
si la versión fuera una versión PEP 440 válida, de lo contrario, la analizará como aLegacyVersion
". (mientras queversion.Version
subiríaInvalidVersion
; fuente )Puede usar el paquete semver para determinar si una versión cumple un requisito de versión semántica . Esto no es lo mismo que comparar dos versiones reales, pero es un tipo de comparación.
Por ejemplo, la versión 3.6.0 + 1234 debería ser la misma que 3.6.0.
fuente
Publicar mi función completa basada en la solución de Kindall. Pude admitir cualquier carácter alfanumérico mezclado con los números al rellenar cada sección de la versión con ceros a la izquierda.
Aunque ciertamente no es tan bonito como su función de una línea, parece funcionar bien con números de versión alfanuméricos. (Solo asegúrese de establecer el
zfill(#)
valor de manera adecuada si tiene cadenas largas en su sistema de versiones)..
fuente
De la manera que lo
setuptools
hace, usa lapkg_resources.parse_version
función. Debe ser compatible con PEP440 .Ejemplo:
fuente
pkg_resources
es parte desetuptools
, que depende depackaging
. Vea otras respuestas que discutenpackaging.version.parse
, que tiene una implementación idéntica apkg_resources.parse_version
.Estaba buscando una solución que no agregara ninguna dependencia nueva. Consulte la siguiente solución (Python 3):
EDITAR: variante agregada con comparación de tuplas. Por supuesto, la variante con comparación de tuplas es mejor, pero estaba buscando la variante con comparación de enteros
fuente