[python] 파이썬과 핍, 사용 가능한 패키지의 모든 버전을 나열합니까?

pip 로 설치할 수있는 Python 패키지의 이름이 주어지면 pip 로 설치할 수있는 모든 가능한 버전 목록을 찾을 수있는 방법이 있습니까? 지금은 시행 착오입니다.

타사 라이브러리 용 버전을 설치하려고하는데 최신 버전이 너무 새 버전이므로 이전 버전과 호환되지 않는 변경 사항이있었습니다. 그래서 어떻게 든 pip가 알고있는 모든 버전의 목록을 가지고 싶습니다. 그래서 테스트 할 수 있습니다.



답변

(업데이트 : 2020 년 3 월 현재 많은 사람들이을 통해 설치된 노른자 pip install yolk3k가 최신 버전 만 반환 한다고보고했습니다 . Chris의 답변 이 가장지지가 높고 저를 위해 일한 것 같습니다)

pastebin의 스크립트가 작동합니다. 그러나 여러 환경 / 호스트로 작업하는 경우 매번 복사 / 생성해야하므로 매우 편리하지 않습니다.

더 나은 만능 솔루션은 pip로 설치할 수있는 yolk3k 를 사용 하는 것입니다. 예를 들어 어떤 장고 버전을 사용할 수 있는지 확인하십시오.

$ 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

yolk3k2012 년에yolk 개발을 중단 한 원본의 포크입니다 . 비록 (아래 설명에 표시된대로) 더 이상 유지되지 않는 것으로 나타나고 파이썬 3를 지원합니다.yolkyolk3k

참고 : 나는 yolk3k의 개발에 관여하지 않습니다. 무언가가 제대로 작동하지 않는 경우 여기에 의견을 남기면 큰 차이가 없습니다. 사용 yolk3k 이슈 트래커를 대신 가능하면 수정을 제출하는 것이 좋습니다.


답변

대한 핍> = 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아닌 모든 문자열이 될 수 있습니다 .


답변

업데이트 :
2017 년 9 월 현재이 방법은 더 이상 작동하지 않습니다 --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"))

이 코드는 다음과 같이 인쇄됩니다 (2015 년 2 월 23 일 기준).

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


답변

Dead-Simple bash 스크립트를 생각해 냈습니다. 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

업데이트 : 버전 번호별로 정렬을 추가하십시오.


답변

노른자 대신 노른자 3k 패키지를 사용할 수 있습니다. yolk3k는 원래의 노른자위의 포크이며 python2와 3을 모두 지원합니다.

https://github.com/myint/yolk

pip install yolk3k


답변

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]