Python и pip, перечислите все версии пакета, который доступен?
дано имя питона (2.Пакет X), который может быть установлен с pip и virtualenv, есть ли способ узнать список всех возможных версий, что pip может установить? Сейчас это метод проб и ошибок.
Я пытаюсь установить версию для сторонней библиотеки, но самая новая версия слишком новая, были сделаны обратные несовместимые изменения. Поэтому я хотел бы каким-то образом иметь список всех версий, о которых знает Пип, поэтому что я могу их проверить.
17 ответов:
скрипт в pastebin действительно работает. Однако это не очень удобно, если вы работаете с несколькими средами/хостами, потому что вам придется копировать/создавать его каждый раз.
лучшим универсальным решением было бы использовать желток, который доступен для установки с pip. Например, чтобы узнать, какие версии Django доступны:
$ pip install yolk $ 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небольшое предостережение: желток зависит от распределения. Это не плохо, но это может быть проблемой, если вам нужно для некоторых причина придерживаться (устаревших) python setuptools.
Примечание: Я не участвую в разработке желтка. если что-то не работает так, как надо, оставив комментарий здесь не должно иметь большого значения. использовать желток баг-трекере вместо этого и рассмотреть вопрос о представлении исправления, если это возможно.
на 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==– все доступные версии, будет печататься без скачивания или установки каких-либо дополнительных пакетов.
на pip использовать
pip install pylibmc==blorkздесь
blorkможет быть любая строка, которая вряд ли будет кандидатом на установку.
обновление:
по состоянию на сентябрь 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)
вам не нужен третий пакет, чтобы получить эту информацию. 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
вы могли бы пакет yolk3k вместо желтка. yolk3k-это вилка из оригинального желтка, и она поддерживает как python2, так и 3.
pip install yolk3k
посмотрев на код pip некоторое время, похоже, что код, ответственный за поиск пакетов, можно найти в
PackageFinderклассpip.index. Его методfind_requirementищет версии aInstallRequirement, но, к сожалению, возвращает только последнюю версию.приведенный ниже код почти 1: 1 копия исходной функции, с возвращением в строке 114 изменен, чтобы вернуть все версии.
сценарий ожидает одно имя пакета в качестве первого и единственного аргумента и возвращает все версии.
я не могу гарантировать правильность, так как я не знаком с кодом Пипа. но, надеюсь, это помогает.
пример вывода
$ 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]
Я придумал dead-простой скрипт bash. Спасибо jq'автора.
#!/bin/bash set -e PACKAGE_JSON_URL="https://pypi.python.org/pypi//json" curl -s "$PACKAGE_JSON_URL" | jq -r '.releases | keys | .[]' | sort -Vобновление: добавить сортировку по номеру версии.
https://pypi.python.org/pypi/Django/ - работает для пакетов, чьи сопровождающие предпочитают показывать все пакеты https://pypi.python.org/simple/pip/ - должен сделать трюк так или иначе (перечисляет все ссылки)
мне не повезло с
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 ...
7.1.0 Типун удалила ... нет-установите опцию Установить. Я нашел способ получить все версии пакета без какого-либо дополнительного пакета.
$ pip install --no-deps Django==x.x.x Collecting Django==x.x.x. Could not find a version that satisfies the requirement Django==x.x.x. (from versions: 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.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.8a1, 1.8b1, 1.8b2, 1.8rc1, 1.8, 1.8.1, 1.8.2) No matching distribution found for Django==x.x.x.
это работает для меня на 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 -11.10.0rc2имейте в виду
gsortдолжен быть установлен (на OSX) для разбора версий. Вы можете установить его с помощьюbrew install coreutils
Я знаю, что это глупо, но вы можете попробовать что-то вроде этого:
pip install django == xэто приведет к ошибке, но перечислит все версии, доступные для этого пакета.
просто заменить
djangoС пакетом, который вы хотите, а также я считаю, надеюсь, нет такой версии под названием x.
Я только что запустил это:
pip show packagenameнапример:
> pip3 show setuptools --- Metadata-Version: 2.0 Name: setuptools Version: 18.4 Summary: Easily download, build, install, upgrade, and uninstall Python packages Home-page: https://bitbucket.org/pypa/setuptools Author: Python Packaging Authority Author-email: [email protected] License: PSF or ZPL Location: /usr/local/lib/python3.4/site-packages Requires:
вы можете использовать этот короткий фрагмент Python3, чтобы захватить список доступных версий для пакета из PyPI. В отличие от некоторых других решений Python, опубликованных здесь, это не разбивается на свободные версии, такие как
django' s1.10rc1илиuwsgi' s2.0.13.1:>>> import requests >>> from pkg_resources import parse_version >>> >>> def versions(name): ... url = "https://pypi.python.org/pypi/{}/json".format(name) ... return sorted(requests.get(url).json()["releases"], key=parse_version) ... >>> print(*reversed(versions("Django")), sep="\n") 1.10.3 1.10.2 1.10.1 1.10 1.10rc1 1.10b1 1.10a1 ...
вот текущий метод на основе Python pip, поиск устаревшего API пакета PyPi:
from pip import index import requests finder = index.PackageFinder( [], ['https://pypi.python.org/simple'], session=requests.Session() ) results = finder.find_all_candidates("package_name") versions = [p.version for p in results]
My take-это комбинация нескольких опубликованных ответов с некоторыми изменениями, чтобы упростить их использование из запущенной среды python.
идея состоит в том, чтобы предоставить совершенно новую команду (смоделированную после команды install), которая дает вам экземпляр package finder для использования. Преимущество заключается в том, что он работает и использует любые индексы, которые pip поддерживает и читает ваши локальные файлы конфигурации pip, поэтому вы получаете правильные результаты, как и с обычным pip установить.
Я сделал попытку сделать его совместимым с обоими pip v 9.x и 10.икс.. но только попробовал его на 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
вы можете grep результат вашего
pip list-> % pip list | grep 'beautifulsoup4' beautifulsoup4 (4.4.1)
Comments