Python та pip, перелічіть усі доступні версії пакету?


445

Враховуючи назву пакета Python, який можна встановити за допомогою pip , чи є спосіб дізнатись список усіх можливих версій цього файлу, який може встановити pip? Зараз це пробні помилки.

Я намагаюся встановити версію для сторонньої бібліотеки, але найновіша версія занадто нова, там були внесені зворотні несумісні зміни. Тож я хотів би якось скласти список усіх версій, про які знає pip, щоб я міг їх перевірити.


1
Прийнята відповідь не еквівалентна іншій зі сценарієм, оскільки вони не генерують однаковий результат.
олігофрен

17
Будь ласка, оновіть вибрану відповідь. Жовток розбивається і непотрібний. Відповідь pip install pylibmc==ідеальна.
Джонатан

Оновіть прийняту відповідь так, як пропонує @Jonathan. Я б не назвав це ідеальним, оскільки він не працюватиме на більш ранніх версіях pip (v7 або v8), але чудово інакше.
Антоні Хеткінс

1
@ Рорі, будь ласка, оновіть прийняту відповідь, жовток мертвий. Відповідь Кріса Монтанаро - найкращий в даний час метод ІМО.
Райан Фішер

1
@Rory Будь-ласка, змініть прийняту відповідь на користь майбутніх відвідувачів цього популярного питання. Проект Yolk більше не підтримується, і він просто не працює, як стверджує ця відповідь.
Вім

Відповіді:


167

(оновлення: Станом на березень 2020 року, багато людей повідомили, що жовток, встановлений через pip install yolk3k, повертає лише останню версію. Відповідь Кріса, схоже, найбільше оновлень і працював на мене)

Сценарій на пастібіні справді працює. Однак це не дуже зручно, якщо ви працюєте з кількома середовищами / хостами, тому що вам доведеться кожного разу копіювати / створювати.

Кращим варіантом рішення було б використовувати yolk3k , який можна встановити за допомогою pip. Наприклад, щоб побачити, які версії Django доступні:

$ 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- вилка оригіналу, yolkяка припинила розвиток у 2012 році . Хоча yolkце більше не підтримується (як зазначено в коментарях нижче), yolk3kсхоже, є і підтримує Python 3.

Примітка: я не беру участь у розробці жовтка3k. Якщо щось, здається, не працює так, як слід, залишати коментар тут не має великого значення. Замість цього скористайтеся трекером проблем yolk3k і, якщо можливо, розгляньте можливість виправити виправлення.


4
Відповідь нижче (використовуючи скрипт з pastebin) більш громіздкий, але принаймні працює в моєму випадку (пошук версій scipy). жовток показує лише останню доступну версію, інший сценарій показує всі версії, що починаються з 0.8.0.
олігофрен

30
Більшу частину часу він поверне лише новітню версію
PawelRoman

17
Ялиця python3 просто використовуйте pip install yolk3k. Команда жовток буде доступна.
П'єр Кріуланссі

8
Як і жовток, більшу частину часу yolk3k повертає лише нову версію.
diabloneo

4
жовток руйнується / більше не підтримується. видалити цю відповідь.
Вім

836

Для pip> = 9,0 використання

$ 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==

- всі доступні версії будуть надруковані без фактичного завантаження чи встановлення додаткових пакетів.

Для піп <9,0 використання

pip install pylibmc==blork

де blorkможе бути будь-який рядок, що не є дійсним номером версії .


25
Мені здається дивним, що помилка піпі виплющує всі версії, але у них немає аргументу, щоб явно дістатись до зазначених даних
Chris Montanaro

2
Ще одна приємна властивість цього рішення - це те, що він працює з усіма нормальними прапорами, щоб обмежити джерела встановлення. Наприклад pip install --only-binary :all: pylibmc, перелічуються всі версії pylibmc, доступні у вигляді двійкових пакетів.
павон

3
pip install pylibmc==9999999 | tr ', ' "\n" | sort -n
Вікас

18
Це має бути позначено як правильну відповідь, оскільки це не вимагає встановлення будь-яких інших пакетів.
Ів Дорфсман

5
Це трохи смішно, що це, здається, єдиний спосіб зробити це в pip. Я сподіваюся, що на їхньому трекері помилок є принаймні відкрите питання про це?
pmos

69

Оновлення:
станом на вересень 2017 року цей метод більше не працює: --no-installбув видалений у pip 7

Використовуйте pip install -v, ви можете побачити всі наявні версії

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

Щоб не встановлювати жоден пакет, використовуйте одне з наступних рішень:

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

або

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

Тестовано з pip 1.0

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

9
pip 1.5.4дає DEPRECATION: --no-install, --no-download, --build, and --no-clean are deprecated. See https://github.com/pypa/pip/issues/906.та не показує доступні версії для вже встановлених пакетів.
int_ua

2
щоб показати всі версії, просто потрібно -v. Решта моєї відповіді полягає в тому, щоб уникнути ефекту додавання (встановити / завантажити). Для встановленого кг, просто додайте оновлення. Так, ви можете створити окремий virtualenv, щоб зробити все простіше.
HVNSweeting

2
піп 9.0.1 гавкає:no such option: --no-install
стомлений_обіг_нитпікер

"найновіша версія:" з -v виключає деякі версії.
mmacvicar

55

Для отримання цієї інформації вам не потрібен сторонній пакет. pypi забезпечує прості канали JSON для всіх пакетів під

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

Ось якийсь код Python, використовуючи лише стандартну бібліотеку, яка отримує всі версії.

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"))

Цей код друкує (станом на 23 лютого 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
У JSON є велика кількість гніздування. Раніше я versions = [x for x in data["releases"] if any([y["python_version"] in ['cp26', '2.6'] for y in data["releases"][x]])]знаходив версії, сумісні з Python 2.6. (Я ніде не бачив cp26, але деякі пакунки були, cp27тому я гадаю, що це може існувати і в інших пакунках.)
tripleee

2
Ось спосіб зробити це з curl, jq та сортуванням ("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
Алан Айві

1
Це призводить до ValueErrorвиключення для деяких пакетів, які дотримуються не настільки суворих схем версій. Щоб виправити це для цих пакунків, див. Цю суть .
TrinitronX

застарілий зробить це за вас.
Шаді

18

Я придумав простий скрипт-баш. Завдяки автору 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

Оновлення: Додати сортування за номером версії.


Мені не вдалося дістатися curlдо роботи, можливо, через помилки сертифікатів. wget --no-check-certificateпрацює, але навіть curl -k --insecureнічого не виробляє. Попередження, яке я отримую, wgetговоритьERROR: certificate common name `www.python.org´ doesn´t match requested host name `pypi.python.org´.
трійка

sort -VНе працює на OSX з версією доморощеного проjq
deepelement

16

Можна замість жовтка ви могли отримати пакет yolk3k. yolk3k - це вилка з оригінального жовтка, і вона підтримує і python2, і 3.

https://github.com/myint/yolk

pip install yolk3k

Це було зручно знати, оскільки жовток не працює під python 3.x
Broken Man

1
yolk3k повертає лише встановлену для мене версію:yolk -V attest Attest 0.5.3
Ентоні Хетчкінс,

2
yolk3k, здається, повертає лише останню версію?
mvherweg

16

Певний перегляд коду pip деякий час виглядає, що код, відповідальний за розміщення пакетів, можна знайти в PackageFinderкласі в pip.index. Його метод find_requirementшукає версії InstallRequirement, але, на жаль, повертає лише останню версію.

Код нижче - це майже копія оригінальної функції 1: 1, а повернення у рядку 114 змінено для повернення всіх версій.

Сценарій очікує одного імені пакета як першого і єдиного аргументу і повертає всі версії.

http://pastebin.com/axzdUQhZ

Я не можу гарантувати правильність, оскільки я не знайомий з кодом pip. Але, сподіваємось, це допомагає.

Вибірка зразка

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

Код:

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]

Це працювало набагато краще, ніж відповідь вище. худий $ жовток -V scipy scipy 0.12.0 худий $ python test.py scipy Версії 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
олігофрен

1
Це використання в документах явно не рекомендується : " Ви не повинні використовувати внутрішні API API таким чином "
wim

9

Ви можете використовувати цей невеликий сценарій Python 3 (використовуючи лише стандартні модулі бібліотеки), щоб схопити список доступних версій для пакету від PyPI за допомогою API JSON та роздрукувати їх у зворотному хронологічному порядку. На відміну від деяких інших рішень Python, розміщених тут, це не розбивається на вільні версії, такі як django's 2.2rc1або uwsgi' s 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')

Збережіть скрипт і запустіть його з назвою пакета як аргумент, наприклад:

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

Це працює для мене на OSX:

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

Він повертає список по одному рядку:

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

Або отримати найновішу версію:

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

Майте на увазі, що gsortдля розбору версій потрібно встановити (на OSX). Ви можете встановити його за допомогоюbrew install coreutils


Боже, чому ти навіть опублікував цю відповідь. Відповідь @Chris Montaro працює і елегантно. Це просто непотрібно вводити ускладнення
Брайан Ліч

@BrianLeach smh ... його той самий підхід відфільтровано для використання в сценарії ...
бабуся

1
Для мене працює cygwin / bash, для другого рішення використовуйте сортування, а не gsort у cygwin.
WebComer

Тут python дає, мабуть, більш читабельний код, ніж баш ... дивіться відповідь @eric chiang (сподіваємось :) вище ...
mirekphd

4

Мій проект ludditeмає таку особливість.

Приклад використання:

>>> 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')

У ньому перераховані всі доступні версії пакету, запитуючи API json https://pypi.org/


Було б більш повчально, якби ви сказали нам, чим займається ваш пакет, інакше ви просто рекламуєте своє програмне забезпечення :)
user228395

@ user228395 Я думав, що це досить очевидно, але в ньому перераховані всі доступні версії пакету, саме про це і задається назва запитання. Відредаговано - краще?
Вім

Його робота, звичайно. Отже, це по суті обгортання рішення, представленого @Timofey Stolbov?
користувач228395

1
@ user228395 Я б не назвав це "обгорткою", оскільки у цій відповіді використовується bash, curl та jq - тоді як luddite просто використовує стандартну бібліотеку Python (urllib). Але рішення від Столбова дійсно використовує ту саму кінцеву точку на pypi.org . Чи можу я запитати, що є причиною твого голосування?
Вім

1
Якщо ви перейшли за посиланням на сторінку детальної інформації про проект, ви зможете побачити, що головна особливість проекту - це перевірка requirements.txtфайлів на застарілі пакети. Це більше, ніж пара рядків коду. Для того щоб перевірити requirements.txtфайл, вам потрібна функціональність, щоб перелічити всі версії пакету. Ця частина навмисно відокремлена та частина публічного API luddite. І це джерело Apache License 2.0, я вважаю, що це не дуже справедливо називати пакетом програмного забезпечення "чорна скринька".
Вім

2

У мене не було ніякої удачі з yolk, yolk3kабо , pip install -vале так що я в кінцевому підсумку з допомогою цього (адаптовано до Python 3 з відповіді Еріком Чанга):

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
StrictVersionне працюватиме для багатьох пакетів ( django, uwsgi, psycopg2щоб назвати кілька). Ви можете використовувати parse_version()з setuptools(див. Мою відповідь для прикладу).
Євген Ярмаш

1

Альтернативне рішення - використовувати API складу:

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

Наприклад, для колби:

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

надрукує:

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

Простий bashсценарій, який покладається лише на pythonсебе (я припускаю, що в контексті питання він повинен бути встановлений) і один з curlабо wget. Має припущення, що у вас встановлений setuptoolsпакет для сортування версій (майже завжди встановлених). Він не покладається на зовнішні залежності, такі як:

  • jq які можуть бути відсутні;
  • grepі awkце може поводитися по-різному в Linux і 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)))"

Трохи довша версія з коментарями.

Введіть назву пакета в змінну:

PACKAGE=requests

Отримайте версії (використовуючи 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)))")

Отримайте версії (використовуючи 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)))")

Роздрукувати відсортовані версії:

echo $VERSIONS

-1

Моя думка - це комбінація декількох опублікованих відповідей, з деякими модифікаціями, щоб полегшити їх використання з поточного середовища python.

Ідея полягає у наданні абсолютно нової команди (за зразком після команди встановлення), яка дає вам примірник пошуку пакета для використання. Перевага полягає в тому, що він працює з і використовує будь-які індекси, які підтримує pip та читають ваші локальні файли конфігурації, тому ви отримуєте правильні результати, як і при звичайній установці файлу.

Я зробив спробу зробити його сумісним з обома pip v 9.x та 10.x .., але спробував лише на 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())

Приклад виведення

./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

це використання в документах явно відмовляє : " Ви не повинні використовувати внутрішні API API таким чином "
wim
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.