Python e pip, elenca tutte le versioni di un pacchetto disponibile?


445

Dato il nome di un pacchetto Python che può essere installato con pip , c'è un modo per scoprire un elenco di tutte le possibili versioni che pip potrebbe installare? In questo momento sono tentativi ed errori.

Sto cercando di installare una versione per una libreria di terze parti, ma la versione più recente è troppo nuova, sono state apportate modifiche incompatibili all'indietro. Quindi vorrei in qualche modo avere un elenco di tutte le versioni che pip conosce, in modo da poterle testare.


1
La risposta accettata non è equivalente all'altra con lo script in quanto non generano lo stesso output.
oligofren,

17
Aggiorna la risposta selezionata. Il tuorlo è rotto e non necessario. La risposta con pip install pylibmc==è perfetta.
Jonathan,

Aggiorna la risposta accettata come suggerisce @Jonathan. Non lo definirei perfetto perché non funzionerà con le versioni precedenti di pip (v7 o v8), ma per il resto è ottimo.
Antony Hatchkins,

1
@Rory aggiorna la risposta accettata, il tuorlo è morto. La risposta di Chris Montanaro è attualmente il miglior metodo IMO.
Ryan Fisher,

1
@Rory Modifica la risposta accettata a beneficio dei futuri visitatori di questa popolare domanda. Il progetto del tuorlo non è più mantenuto e semplicemente non funziona come sostiene la risposta.
mercoledì

Risposte:


167

(aggiornamento: a partire da marzo 2020, molte persone hanno riferito che il tuorlo, installato tramite pip install yolk3k, restituisce solo l'ultima versione. La risposta di Chris sembra avere il maggior numero di voti e ha funzionato per me)

Lo script su pastebin funziona. Tuttavia non è molto conveniente se lavori con più ambienti / host perché dovrai copiarlo / crearlo ogni volta.

Una soluzione completa migliore sarebbe quella di utilizzare yolk3k , che è disponibile per l'installazione con pip. Ad esempio per vedere quali versioni di Django sono disponibili:

$ pip install yolk3k
$ yolk -V django
Django 1.3
Django 1.2.5
Django 1.2.4
Django 1.2.3
Django 1.2.2
Django 1.2.1
Django 1.2
Django 1.1.4
Django 1.1.3
Django 1.1.2
Django 1.0.4

yolk3kè un fork dell'originale yolkche ha cessato lo sviluppo nel 2012 . Sebbene yolknon sia più mantenuto (come indicato nei commenti seguenti), yolk3ksembra essere e supporta Python 3.

Nota: non sono coinvolto nello sviluppo di yolk3k. Se qualcosa non sembra funzionare come dovrebbe, lasciare un commento qui non dovrebbe fare molta differenza. Utilizzare invece il localizzatore di problemi yolk3k e, se possibile, considerare di inviare una correzione.


4
La risposta che segue (usando lo script di pastebin) è più ingombrante, ma almeno funziona nel mio caso (cercare versioni di scipy). tuorlo mostra solo l'ultima versione disponibile, l'altro script mostra tutte le versioni risalenti alla 0.8.0.
oligofren,

31
Il più delle volte restituirà solo la versione più recente
PawelRoman il

17
Fir python3 usa solo pip install yolk3k. Il comando tuorlo sarà disponibile.
Pierre Criulanscy,

9
Come il tuorlo, il più delle volte yolk3k restituisce solo la versione più recente.
diabloneo,

4
il tuorlo è rotto / non più mantenuto. cancella questa risposta.
mercoledì

840

Per pip> = 9.0 utilizzare

$ pip install pylibmc==
Collecting pylibmc==
  Could not find a version that satisfies the requirement pylibmc== (from 
  versions: 0.2, 0.3, 0.4, 0.5.1, 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5, 0.6.1, 0.6, 
  0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.7, 0.8.1, 0.8.2, 0.8, 0.9.1, 0.9.2, 0.9, 
  1.0-alpha, 1.0-beta, 1.0, 1.1.1, 1.1, 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.3.0)
No matching distribution found for pylibmc==

- tutte le versioni disponibili verranno stampate senza scaricare o installare pacchetti aggiuntivi.

Per pip <9.0 usare

pip install pylibmc==blork

dove blorkpuò essere qualsiasi stringa che non è un numero di versione valido .


25
Trovo strano che l'errore di pip sputi tutte le versioni ma non hanno alcun argomento per ottenere esplicitamente tali dati
Chris Montanaro,

2
Un'altra bella proprietà di questa soluzione è che funziona con tutti i normali flag per limitare le fonti di installazione. Ad esempio pip install --only-binary :all: pylibmcelencherà tutte le versioni di pylibmc disponibili come pacchetti binari.
pavone

3
pip install pylibmc==9999999 | tr ', ' "\n" | sort -n
Vikas,

18
Questo dovrebbe essere contrassegnato come la risposta corretta in quanto non richiede l'installazione di altri pacchetti.
Yves Dorfsman,

5
È un po 'ridicolo che questo sembra essere l'unico modo per farlo in pip. Spero che ci sia almeno un problema aperto su questo sul loro bug tracker?
pmos,

69

Aggiornamento:
da settembre 2017 questo metodo non funziona più: è --no-installstato rimosso nel pip 7

Usa pip install -v, puoi vedere tutte le versioni disponibili

root@node7:~# pip install web.py -v
Downloading/unpacking web.py
  Using version 0.37 (newest of versions: 0.37, 0.36, 0.35, 0.34, 0.33, 0.33, 0.32, 0.31, 0.22, 0.2)
  Downloading web.py-0.37.tar.gz (90Kb): 90Kb downloaded
  Running setup.py egg_info for package web.py
    running egg_info
    creating pip-egg-info/web.py.egg-info

Per non installare alcun pacchetto, utilizzare una delle seguenti soluzioni:

root@node7:~# pip install --no-deps --no-install flask -v                                                                                                      
Downloading/unpacking flask
  Using version 0.10.1 (newest of versions: 0.10.1, 0.10, 0.9, 0.8.1, 0.8, 0.7.2, 0.7.1, 0.7, 0.6.1, 0.6, 0.5.2, 0.5.1, 0.5, 0.4, 0.3.1, 0.3, 0.2, 0.1)
  Downloading Flask-0.10.1.tar.gz (544Kb): 544Kb downloaded

o

root@node7:~# cd $(mktemp -d)
root@node7:/tmp/tmp.c6H99cWD0g# pip install flask -d . -v
Downloading/unpacking flask
  Using version 0.10.1 (newest of versions: 0.10.1, 0.10, 0.9, 0.8.1, 0.8, 0.7.2, 0.7.1, 0.7, 0.6.1, 0.6, 0.5.2, 0.5.1, 0.5, 0.4, 0.3.1, 0.3, 0.2, 0.1)
  Downloading Flask-0.10.1.tar.gz (544Kb): 4.1Kb downloaded

Testato con pip 1.0

root@node7:~# pip --version
pip 1.0 from /usr/lib/python2.7/dist-packages (python 2.7)

9
pip 1.5.4fornisce DEPRECATION: --no-install, --no-download, --build, and --no-clean are deprecated. See https://github.com/pypa/pip/issues/906.e non mostra le versioni disponibili per i pacchetti che sono già installati.
int_ua,

2
per mostrare tutte le versioni, ha solo bisogno -v. Il resto della mia risposta è per evitare l'effetto addizione (installa / scarica). Per pkg installato, basta aggiungere --upgrade. Anw, puoi creare un virtualenv separato per rendere tutto più semplice.
HVN:

2
pip 9.0.1 abbaia:no such option: --no-install
tired_of_nitpickers il

"versione più recente:" da -v esclude alcune versioni.
mmacvicar,

55

Non è necessario un pacchetto di terze parti per ottenere queste informazioni. pypi fornisce semplici feed JSON per tutti i pacchetti in

https://pypi.python.org/pypi/{PKG_NAME}/json

Ecco un po 'di codice Python usando solo la libreria standard che ottiene tutte le versioni.

import json
import urllib2
from distutils.version import StrictVersion

def versions(package_name):
    url = "https://pypi.python.org/pypi/%s/json" % (package_name,)
    data = json.load(urllib2.urlopen(urllib2.Request(url)))
    versions = data["releases"].keys()
    versions.sort(key=StrictVersion)
    return versions

print "\n".join(versions("scikit-image"))

Quel codice viene stampato (dal 23 febbraio 2015):

0.7.2
0.8.0
0.8.1
0.8.2
0.9.0
0.9.1
0.9.2
0.9.3
0.10.0
0.10.1

2
Il JSON ha una buona quantità di nidificazione. Ho usato versions = [x for x in data["releases"] if any([y["python_version"] in ['cp26', '2.6'] for y in data["releases"][x]])]per trovare versioni compatibili con Python 2.6. (Non ho visto da cp26nessuna parte, ma alcuni pacchetti avevano cp27quindi
suppongo

2
Ecco un modo per farlo con curl, jq e sort (un "one-liner"!): curl -s https://pypi.python.org/pypi/{PKG_NAME}/json | jq -r '.releases | keys[]' | sort -t. -k 1,1n -k 2,2n -k 3,3n
Alan Ivey,

1
Ciò genera ValueErrorun'eccezione per alcuni pacchetti che seguono schemi di versioning non così rigorosi. Per correggerlo per questi pacchetti, vedere questo riassunto .
TrinitronX,

obsoleto lo farà per te.
Shadi,

18

Mi è venuta in mente una sceneggiatura bash estremamente semplice. Grazie all'autore di jq .

#!/bin/bash
set -e

PACKAGE_JSON_URL="https://pypi.org/pypi/${1}/json"

curl -s "$PACKAGE_JSON_URL" | jq  -r '.releases | keys | .[]' | sort -V

Aggiornamento: aggiungi l'ordinamento per numero di versione.


Non sono riuscito a mettermi curlal lavoro, probabilmente a causa di errori nel certificato. wget --no-check-certificatefunziona, ma curl -k --insecurenon produce nemmeno nulla. L'avvertimento che ricevo wgetdiceERROR: certificate common name `www.python.org´ doesn´t match requested host name `pypi.python.org´.
triplo

The sort -Vnon funziona su OSX con la versione homebrew dijq
deepelement

16

È possibile il pacchetto yolk3k anziché tuorlo. yolk3k è un fork dal tuorlo originale e supporta sia python2 che 3.

https://github.com/myint/yolk

pip install yolk3k

Questo è stato utile da sapere, dal momento che il tuorlo non funziona con Python 3.x
Broken Man

1
yolk3k restituisce solo la versione installata per me:yolk -V attest Attest 0.5.3
Antony Hatchkins,

2
yolk3k sembra restituire solo l'ultima versione?
mvherweg,

16

Dopo aver esaminato il codice di pip per un po ', sembra che il codice responsabile per l'individuazione dei pacchetti possa essere trovato nella PackageFinderclasse in pip.index. Il suo metodo find_requirementcerca le versioni di a InstallRequirement, ma purtroppo restituisce solo la versione più recente.

Il codice seguente è quasi una copia 1: 1 della funzione originale, con il ritorno nella riga 114 modificato per restituire tutte le versioni.

Lo script prevede un nome di pacchetto come primo e unico argomento e restituisce tutte le versioni.

http://pastebin.com/axzdUQhZ

Non posso garantire la correttezza, poiché non ho familiarità con il codice pip. Ma spero che questo aiuti.

Uscita campione

python test.py pip
Versions of pip
0.8.2
0.8.1
0.8
0.7.2
0.7.1
0.7
0.6.3
0.6.2
0.6.1
0.6
0.5.1
0.5
0.4
0.3.1
0.3
0.2.1
0.2 dev

Il codice:

import posixpath
import pkg_resources
import sys
from pip.download import url_to_path
from pip.exceptions import DistributionNotFound
from pip.index import PackageFinder, Link
from pip.log import logger
from pip.req import InstallRequirement
from pip.util import Inf


class MyPackageFinder(PackageFinder):

    def find_requirement(self, req, upgrade):
        url_name = req.url_name
        # Only check main index if index URL is given:
        main_index_url = None
        if self.index_urls:
            # Check that we have the url_name correctly spelled:
            main_index_url = Link(posixpath.join(self.index_urls[0], url_name))
            # This will also cache the page, so it's okay that we get it again later:
            page = self._get_page(main_index_url, req)
            if page is None:
                url_name = self._find_url_name(Link(self.index_urls[0]), url_name, req) or req.url_name

        # Combine index URLs with mirror URLs here to allow
        # adding more index URLs from requirements files
        all_index_urls = self.index_urls + self.mirror_urls

        def mkurl_pypi_url(url):
            loc = posixpath.join(url, url_name)
            # For maximum compatibility with easy_install, ensure the path
            # ends in a trailing slash.  Although this isn't in the spec
            # (and PyPI can handle it without the slash) some other index
            # implementations might break if they relied on easy_install's behavior.
            if not loc.endswith('/'):
                loc = loc + '/'
            return loc
        if url_name is not None:
            locations = [
                mkurl_pypi_url(url)
                for url in all_index_urls] + self.find_links
        else:
            locations = list(self.find_links)
        locations.extend(self.dependency_links)
        for version in req.absolute_versions:
            if url_name is not None and main_index_url is not None:
                locations = [
                    posixpath.join(main_index_url.url, version)] + locations

        file_locations, url_locations = self._sort_locations(locations)

        locations = [Link(url) for url in url_locations]
        logger.debug('URLs to search for versions for %s:' % req)
        for location in locations:
            logger.debug('* %s' % location)
        found_versions = []
        found_versions.extend(
            self._package_versions(
                [Link(url, '-f') for url in self.find_links], req.name.lower()))
        page_versions = []
        for page in self._get_pages(locations, req):
            logger.debug('Analyzing links from page %s' % page.url)
            logger.indent += 2
            try:
                page_versions.extend(self._package_versions(page.links, req.name.lower()))
            finally:
                logger.indent -= 2
        dependency_versions = list(self._package_versions(
            [Link(url) for url in self.dependency_links], req.name.lower()))
        if dependency_versions:
            logger.info('dependency_links found: %s' % ', '.join([link.url for parsed, link, version in dependency_versions]))
        file_versions = list(self._package_versions(
                [Link(url) for url in file_locations], req.name.lower()))
        if not found_versions and not page_versions and not dependency_versions and not file_versions:
            logger.fatal('Could not find any downloads that satisfy the requirement %s' % req)
            raise DistributionNotFound('No distributions at all found for %s' % req)
        if req.satisfied_by is not None:
            found_versions.append((req.satisfied_by.parsed_version, Inf, req.satisfied_by.version))
        if file_versions:
            file_versions.sort(reverse=True)
            logger.info('Local files found: %s' % ', '.join([url_to_path(link.url) for parsed, link, version in file_versions]))
            found_versions = file_versions + found_versions
        all_versions = found_versions + page_versions + dependency_versions
        applicable_versions = []
        for (parsed_version, link, version) in all_versions:
            if version not in req.req:
                logger.info("Ignoring link %s, version %s doesn't match %s"
                            % (link, version, ','.join([''.join(s) for s in req.req.specs])))
                continue
            applicable_versions.append((link, version))
        applicable_versions = sorted(applicable_versions, key=lambda v: pkg_resources.parse_version(v[1]), reverse=True)
        existing_applicable = bool([link for link, version in applicable_versions if link is Inf])
        if not upgrade and existing_applicable:
            if applicable_versions[0][1] is Inf:
                logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
                            % req.satisfied_by.version)
            else:
                logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
                            % (req.satisfied_by.version, applicable_versions[0][1]))
            return None
        if not applicable_versions:
            logger.fatal('Could not find a version that satisfies the requirement %s (from versions: %s)'
                         % (req, ', '.join([version for parsed_version, link, version in found_versions])))
            raise DistributionNotFound('No distributions matching the version for %s' % req)
        if applicable_versions[0][0] is Inf:
            # We have an existing version, and its the best version
            logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
                        % (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
            return None
        if len(applicable_versions) > 1:
            logger.info('Using version %s (newest of versions: %s)' %
                        (applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))
        return applicable_versions


if __name__ == '__main__':
    req = InstallRequirement.from_line(sys.argv[1], None)
    finder = MyPackageFinder([], ['http://pypi.python.org/simple/'])
    versions = finder.find_requirement(req, False)
    print 'Versions of %s' % sys.argv[1]
    for v in versions:
        print v[1]

Questo ha funzionato molto meglio della risposta sopra. magro $ tuorlo -V scipy scipy 0.12.0 magro $ python test.py scipy Versioni di scipy 0.12.0 0.12.0 0.11.0 0.11.0 0.10.1 0.10.1 0.10.0 0.10.0 0.9.0 0.9.0 0.8.0
oligofren,

1
Questo uso è esplicitamente scoraggiato nei documenti : " non è necessario utilizzare le API interne di pip in questo modo "
wim

9

È possibile utilizzare questo piccolo script Python 3 (utilizzando solo i moduli di libreria standard) per acquisire l'elenco delle versioni disponibili per un pacchetto da PyPI utilizzando l' API JSON e stamparle in ordine cronologico inverso. A differenza di altre soluzioni Python pubblicate qui, questo non si interrompe su versioni libere come django' 2.2rc1o uwsgi' 2.0.17.1:

#!/usr/bin/env python3

import json
import sys
from urllib import request    
from pkg_resources import parse_version    

def versions(pkg_name):
    url = f'https://pypi.python.org/pypi/{pkg_name}/json'
    releases = json.loads(request.urlopen(url).read())['releases']
    return sorted(releases, key=parse_version, reverse=True)    

if __name__ == '__main__':
    print(*versions(sys.argv[1]), sep='\n')

Salvare lo script ed eseguirlo con il nome del pacchetto come argomento, ad esempio:

python versions.py django
3.0a1
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2
2.2rc1
...


7

Questo funziona per me su OSX:

pip install docker-compose== 2>&1 \
| grep -oE '(\(.*\))' \
| awk -F:\  '{print$NF}' \
| sed -E 's/( |\))//g' \
| tr ',' '\n'

Restituisce l'elenco uno per riga:

1.1.0rc1
1.1.0rc2
1.1.0
1.2.0rc1
1.2.0rc2
1.2.0rc3
1.2.0rc4
1.2.0
1.3.0rc1
1.3.0rc2
1.3.0rc3
1.3.0
1.3.1
1.3.2
1.3.3
1.4.0rc1
1.4.0rc2
1.4.0rc3
1.4.0
1.4.1
1.4.2
1.5.0rc1
1.5.0rc2
1.5.0rc3
1.5.0
1.5.1
1.5.2
1.6.0rc1
1.6.0
1.6.1
1.6.2
1.7.0rc1
1.7.0rc2
1.7.0
1.7.1
1.8.0rc1
1.8.0rc2
1.8.0
1.8.1
1.9.0rc1
1.9.0rc2
1.9.0rc3
1.9.0rc4
1.9.0
1.10.0rc1
1.10.0rc2
1.10.0

O per ottenere l'ultima versione disponibile:

pip install docker-compose== 2>&1 \
| grep -oE '(\(.*\))' \
| awk -F:\  '{print$NF}' \
| sed -E 's/( |\))//g' \
| tr ',' '\n' \
| gsort -r -V \
| head -1
1.10.0rc2

Tieni presente che gsortdeve essere installato (su OSX) per analizzare le versioni. Puoi installarlo conbrew install coreutils


Accidenti perché hai postato questa risposta. La risposta di @Chris Montaro funziona ed è elegante. Ciò introduce inutilmente complicazioni
Brian Leach

@BrianLeach smh ... è lo stesso approccio filtrato per l'uso in uno script ...
nonna

1
Funziona in cygwin / bash per me, per la seconda soluzione usa sort, non gsort in cygwin.
WebComer,

Qui python produce probabilmente un codice più leggibile di bash ... vedi la risposta di @eric chiang (si spera :) sopra ...
mirekphd,

4

Il mio progetto ludditeha questa funzione.

Esempio di utilizzo:

>>> import luddite
>>> luddite.get_versions_pypi("python-dateutil")
('0.1', '0.3', '0.4', '0.5', '1.0', '1.1', '1.2', '1.4', '1.4.1', '1.5', '2.0', '2.1', '2.2', '2.3', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.7.4', '2.7.5', '2.8.0')

Elenca tutte le versioni di un pacchetto disponibile, interrogando l'API json di https://pypi.org/


Sarebbe più istruttivo se ci dicessi cosa sta facendo il tuo pacchetto, altrimenti stai solo promuovendo il tuo software :)
user228395

@ user228395 Ho pensato che fosse abbastanza ovvio, ma elenca tutte le versioni di un pacchetto disponibile, che era esattamente ciò di cui si pone il titolo della domanda. Modificato - meglio?
mercoledì

I suoi meccanismi ovviamente. Quindi sta essenzialmente avvolgendo la soluzione presentata da @Timofey Stolbov?
user228395

1
@ user228395 Non lo definirei "wrapping", poiché quella risposta usa bash, curl e jq - mentre luddite usa solo la libreria standard di Python (urllib). Ma la soluzione di Stolbov utilizza lo stesso endpoint su pypi.org . Posso chiederti qual è la ragione del tuo downvote?
mercoledì

1
Se hai seguito il link alla pagina dei dettagli del progetto, potresti vedere che la caratteristica principale del progetto riguarda il controllo dei requirements.txtfile per i pacchetti scaduti. È più di un paio di righe di codice. Per controllare un requirements.txtfile, è necessaria la funzionalità per elencare tutte le versioni del pacchetto. Questa parte è intenzionalmente disaccoppiata e parte dell'API pubblica di luddite. Ed è la fonte Apache License 2.0, penso che non sia proprio corretto definirlo un pacchetto software "black-box".
mercoledì

2

Non ho avuto fortuna con yolk, yolk3ko pip install -vma così ho finito per usarlo (adattato a Python 3 dalla risposta di Eric Chiang):

import json
import requests
from distutils.version import StrictVersion

def versions(package_name):
    url = "https://pypi.python.org/pypi/{}/json".format(package_name)
    data = requests.get(url).json()
    return sorted(list(data["releases"].keys()), key=StrictVersion, reverse=True)

>>> print("\n".join(versions("gunicorn")))
19.1.1
19.1.0
19.0.0
18.0
17.5
0.17.4
0.17.3
...

1
StrictVersionnon funziona per molti pacchetti ( django, uwsgi, psycopg2solo per citarne alcuni). Puoi usare parse_version()da setuptools(vedi la mia risposta per un esempio).
Eugene Yarmash,

1

La soluzione alternativa è utilizzare le API del magazzino:

https://warehouse.readthedocs.io/api-reference/json/#release

Ad esempio per Flask:

import requests
r = requests.get("https://pypi.org/pypi/Flask/json")
print(r.json()['releases'].keys())

stamperà:

dict_keys(['0.1', '0.10', '0.10.1', '0.11', '0.11.1', '0.12', '0.12.1', '0.12.2', '0.12.3', '0.12.4', '0.2', '0.3', '0.3.1', '0.4', '0.5', '0.5.1', '0.5.2', '0.6', '0.6.1', '0.7', '0.7.1', '0.7.2', '0.8', '0.8.1', '0.9', '1.0', '1.0.1', '1.0.2'])

0

bashScript semplice che si basa solo su pythonse stesso (suppongo che nel contesto della domanda debba essere installato) e uno di curlo wget. Presuppone che tu abbia setuptoolsinstallato un pacchetto per ordinare le versioni (quasi sempre installato). Non si basa su dipendenze esterne come:

  • jq che potrebbe non essere presente;
  • grepe awkciò potrebbe comportarsi diversamente su Linux e macOS.
curl --silent --location https://pypi.org/pypi/requests/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))"

Una versione un po 'più lunga con commenti.

Inserisci il nome del pacchetto in una variabile:

PACKAGE=requests

Ottieni versioni (usando curl):

VERSIONS=$(curl --silent --location https://pypi.org/pypi/$PACKAGE/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))")

Ottieni versioni (usando wget):

VERSIONS=$(wget -qO- https://pypi.org/pypi/$PACKAGE/json | python -c "import sys, json, pkg_resources; releases = json.load(sys.stdin)['releases']; print(' '.join(sorted(releases, key=pkg_resources.parse_version)))")

Stampa versioni ordinate:

echo $VERSIONS

-1

La mia opinione è una combinazione di un paio di risposte postate, con alcune modifiche per renderle più facili da usare all'interno di un ambiente Python in esecuzione.

L'idea è di fornire un comando completamente nuovo (modellato sul comando di installazione) che ti dia un'istanza del cercatore di pacchetti da usare. Il lato positivo è che funziona e usa tutti gli indici che pip supporta e legge i file di configurazione pip locali, in modo da ottenere i risultati corretti come si farebbe con una normale installazione pip.

Ho tentato di renderlo compatibile con pip v 9.xe 10.x .. ma l'ho provato solo su 9.x

https://gist.github.com/kaos/68511bd013fcdebe766c981f50b473d4

#!/usr/bin/env python
# When you want a easy way to get at all (or the latest) version of a certain python package from a PyPi index.

import sys
import logging

try:
    from pip._internal import cmdoptions, main
    from pip._internal.commands import commands_dict
    from pip._internal.basecommand import RequirementCommand
except ImportError:
    from pip import cmdoptions, main
    from pip.commands import commands_dict
    from pip.basecommand import RequirementCommand

from pip._vendor.packaging.version import parse as parse_version

logger = logging.getLogger('pip')

class ListPkgVersionsCommand(RequirementCommand):
    """
    List all available versions for a given package from:

    - PyPI (and other indexes) using requirement specifiers.
    - VCS project urls.
    - Local project directories.
    - Local or remote source archives.

    """
    name = "list-pkg-versions"
    usage = """
      %prog [options] <requirement specifier> [package-index-options] ...
      %prog [options] [-e] <vcs project url> ...
      %prog [options] [-e] <local project path> ...
      %prog [options] <archive url/path> ..."""

    summary = 'List package versions.'

    def __init__(self, *args, **kw):
        super(ListPkgVersionsCommand, self).__init__(*args, **kw)

        cmd_opts = self.cmd_opts

        cmd_opts.add_option(cmdoptions.install_options())
        cmd_opts.add_option(cmdoptions.global_options())
        cmd_opts.add_option(cmdoptions.use_wheel())
        cmd_opts.add_option(cmdoptions.no_use_wheel())
        cmd_opts.add_option(cmdoptions.no_binary())
        cmd_opts.add_option(cmdoptions.only_binary())
        cmd_opts.add_option(cmdoptions.pre())
        cmd_opts.add_option(cmdoptions.require_hashes())

        index_opts = cmdoptions.make_option_group(
            cmdoptions.index_group,
            self.parser,
        )

        self.parser.insert_option_group(0, index_opts)
        self.parser.insert_option_group(0, cmd_opts)

    def run(self, options, args):
        cmdoptions.resolve_wheel_no_use_binary(options)
        cmdoptions.check_install_build_global(options)

        with self._build_session(options) as session:
            finder = self._build_package_finder(options, session)

            # do what you please with the finder object here... ;)
            for pkg in args:
                logger.info(
                    '%s: %s', pkg,
                    ', '.join(
                        sorted(
                            set(str(c.version) for c in finder.find_all_candidates(pkg)),
                            key=parse_version,
                        )
                    )
                )


commands_dict[ListPkgVersionsCommand.name] = ListPkgVersionsCommand

if __name__ == '__main__':
    sys.exit(main())

Esempio di output

./list-pkg-versions.py list-pkg-versions pika django
pika: 0.5, 0.5.1, 0.5.2, 0.9.1a0, 0.9.2a0, 0.9.3, 0.9.4, 0.9.5, 0.9.6, 0.9.7, 0.9.8, 0.9.9, 0.9.10, 0.9.11, 0.9.12, 0.9.13, 0.9.14, 0.10.0b1, 0.10.0b2, 0.10.0, 0.11.0b1, 0.11.0, 0.11.1, 0.11.2, 0.12.0b2
django: 1.1.3, 1.1.4, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.2.6, 1.2.7, 1.3, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5, 1.3.6, 1.3.7, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9, 1.4.10, 1.4.11, 1.4.12, 1.4.13, 1.4.14, 1.4.15, 1.4.16, 1.4.17, 1.4.18, 1.4.19, 1.4.20, 1.4.21, 1.4.22, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.7, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10, 1.7.11, 1.8a1, 1.8b1, 1.8b2, 1.8rc1, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.8.10, 1.8.11, 1.8.12, 1.8.13, 1.8.14, 1.8.15, 1.8.16, 1.8.17, 1.8.18, 1.8.19, 1.9a1, 1.9b1, 1.9rc1, 1.9rc2, 1.9, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 1.9.7, 1.9.8, 1.9.9, 1.9.10, 1.9.11, 1.9.12, 1.9.13, 1.10a1, 1.10b1, 1.10rc1, 1.10, 1.10.1, 1.10.2, 1.10.3, 1.10.4, 1.10.5, 1.10.6, 1.10.7, 1.10.8, 1.11a1, 1.11b1, 1.11rc1, 1.11, 1.11.1, 1.11.2, 1.11.3, 1.11.4, 1.11.5, 1.11.6, 1.11.7, 1.11.8, 1.11.9, 1.11.10, 1.11.11, 1.11.12, 2.0, 2.0.1, 2.0.2, 2.0.3, 2.0.4

questo uso è esplicitamente scoraggiato nei documenti : " non devi usare le API interne di pip in questo modo "
wim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.