¿Cómo verificar si el paquete python es la última versión mediante programación?
pip gekko (6)
Versión rápida (solo verificando el paquete)
Este hace el truco de llamar al paquete con una versión no disponible como
pip install package_name==random
y la respuesta da toda la versión disponible, luego el programa lee la última.
Luego ejecuta
pip show package_name
y obtiene la versión actual del paquete.
Si encuentra una coincidencia, devuelve True, de lo contrario False
Esta es una opción confiable dado que se encuentra en
pip
import subprocess
import sys
def check(name):
latest_version = str(subprocess.run([sys.executable, ''-m'', ''pip'', ''install'', ''{}==0''.format(name)], capture_output=True, text=True))
latest_version = latest_version[latest_version.find(''(from versions:'')+15:]
latest_version = latest_version[:latest_version.find('')'')]
latest_version = latest_version.replace('' '','''').split('','')[-1]
current_version = str(subprocess.run([sys.executable, ''-m'', ''pip'', ''show'', ''{}''.format(name)], capture_output=True, text=True))
current_version = current_version[current_version.find(''Version:'')+8:]
current_version = current_version[:current_version.find(''//n'')].replace('' '','''')
if latest_version == current_version:
return True
else:
return False
Éste requiere una
pip list --outdated
import subprocess
import sys
def check(name):
reqs = subprocess.check_output([sys.executable, ''-m'', ''pip'', ''list'',''--outdated''])
outdated_packages = [r.decode().split(''=='')[0] for r in reqs.split()]
return name in outdated_packages
¿Cómo verifica si un paquete está en su última versión mediante programación en un script y devuelve verdadero o falso?
Puedo verificar con un script como este:
package=''gekko''
import pip
if hasattr(pip, ''main''):
from pip import main as pipmain
else:
from pip._internal import main as pipmain
pipmain([''search'',''gekko''])
o con línea de comando:
(base) C:/User>pip search gekko
gekko (0.2.3) - Machine learning and optimization for dynamic systems
INSTALLED: 0.2.3 (latest)
Pero, ¿cómo verifico mediante programación y devuelvo verdadero o falso?
Ultima versión:
Mi proyecto
luddite
tiene esta característica:
>>> import luddite
>>> luddite.get_version_pypi("gekko")
''0.2.3''
Versión instalada:
La forma canónica de verificar la versión instalada es solo para acceder al atributo
__version__
del espacio de nombres de nivel superior:
>>> import gekko
>>> gekko.__version__
''0.2.0''
Lamentablemente, no todos los proyectos establecen este atributo.
Cuando no lo hacen, puede usar
pkg_resources
para extraerlo de los metadatos:
>>> import pkg_resources
>>> pkg_resources.get_distribution("gekko").version
''0.2.0''
Esto debería hacer el truco al menos para fines de demostración.
Simplemente llame a
isLatestVersion
con el nombre del paquete que desea verificar.
Si está utilizando esto en algún lugar importante, querrá probar / capturar la solicitud de URL, ya que es posible que el acceso a Internet no esté disponible.
También tenga en cuenta que si el paquete no está instalado,
isLatestVersion
devolverá False.
Esto se prueba para Python 3.7.4 y Pip 19.0.3.
import pip
import subprocess
import json
import urllib.request
from pip._internal.operations.freeze import freeze
def isLatestVersion(pkgName):
# Get the currently installed version
current_version = ''''
for requirement in freeze(local_only=False):
pkg = requirement.split(''=='')
if pkg[0] == pkgName:
current_version = pkg[1]
# Check pypi for the latest version number
contents = urllib.request.urlopen(''https://pypi.org/pypi/''+pkgName+''/json'').read()
data = json.loads(contents)
latest_version = data[''info''][''version'']
return latest_version == current_version
Mi proyecto
johnnydep
tiene esta característica.
Con cáscara:
pip install --upgrade pip johnnydep
pip install gekko==0.2.0
En Python:
>>> from johnnydep.lib import JohnnyDist
>>> dist = JohnnyDist("gekko")
>>> dist.version_installed
''0.2.0''
>>> dist.version_latest
''0.2.3''
No es difícil escribir un script simple usted mismo
consultando la API de PyPI
.
Con la última versión de Python 3.8, es posible usar solo la biblioteca estándar (cuando se usa Python 3.7 o anterior, tendrá que instalar el
importlib_metadata
):
# check_version.py
import json
import urllib.request
import sys
try:
from importlib.metadata import version
except ImportError:
from importlib_metadata import version
from distutils.version import LooseVersion
if __name__ == ''__main__'':
name = sys.argv[1]
installed_version = LooseVersion(version(name))
# fetch package metadata from PyPI
pypi_url = f''https://pypi.org/pypi/{name}/json''
response = urllib.request.urlopen(pypi_url).read().decode()
latest_version = max(LooseVersion(s) for s in json.loads(response)[''releases''].keys())
print(''package:'', name, ''installed:'', installed_version, ''latest:'', latest_version)
Ejemplo de uso:
$ python check_version.py setuptools
package: setuptools installed: 41.2.0 latest: 41.6.0
Si tiene un
packaging
instalado, es una mejor alternativa a
distutils.version
para el análisis de versiones:
from distutils.version import LooseVersion
...
LooseVersion(s)
se convierte
from packaging.version import parse
...
parse(s)
Editar: Eliminar búsqueda de pip
Gracias por las varias sugerencias.
Aquí hay una nueva versión que no utiliza la
pip search
sino que extrae la última versión directamente de
pypi
como lo propuso
Daniel Hill
.
Esto también resuelve el problema con las coincidencias falsas de la subcadena.
def check(name):
import subprocess
import sys
import json
import urllib.request
# create dictionary of package versions
pkgs = subprocess.check_output([sys.executable, ''-m'', ''pip'', ''freeze''])
keys = [p.decode().split(''=='')[0] for p in pkgs.split()]
values = [p.decode().split(''=='')[1] for p in pkgs.split()]
d = dict(zip(keys, values)) # dictionary of all package versions
# retrieve info on latest version
contents = urllib.request.urlopen(''https://pypi.org/pypi/''+name+''/json'').read()
data = json.loads(contents)
latest_version = data[''info''][''version'']
if d[name]==latest_version:
print(''Latest version ('' + d[name] + '') of ''+str(name)+'' is installed'')
return True
else:
print(''Version '' + d[name] + '' of ''+str(name)+'' not the latest ''+latest_version)
return False
print(check(''gekko''))
Respuesta original
Aquí hay una solución rápida que recupera la información de la última versión solo del paquete de interés
gekko
.
def check(name):
import subprocess
import sys
# create dictionary of package versions
pkgs = subprocess.check_output([sys.executable, ''-m'', ''pip'', ''freeze''])
keys = [p.decode().split(''=='')[0] for p in pkgs.split()]
values = [p.decode().split(''=='')[1] for p in pkgs.split()]
d = dict(zip(keys, values)) # dictionary of all package versions
# retrieve info on latest version
s = subprocess.check_output([sys.executable, ''-m'', ''pip'', ''search'', name])
if d[name] in s.decode(): # weakness
print(''Latest version ('' + d[name] + '') of ''+str(name)+'' is installed'')
return True
else:
print(s.decode())
return False
print(check(''gekko''))
Esto produce el mensaje La
Latest version (0.2.3) of gekko is installed
y devuelve
True
para indicar la última versión (o
False
si no es la última).
Puede que esta no sea la mejor solución porque solo busca una subcadena de versión con
if d[name] in s.decode():
pero es más rápido que la
pip list --outdated
que verifica todos los paquetes.
Este no es el método más confiable porque devolverá un
True
incorrecto si la versión instalada actual es
0.2.3
pero la última versión es
0.2.30
o
0.2.3a
.
Una mejora sería obtener mediante programación la última versión y hacer una comparación directa.