python - कैसे जांच करें कि पायथन पैकेज प्रोग्रामेटिक रूप से नवीनतम संस्करण है?




pip gekko (4)

यदि कोई पैकेज किसी स्क्रिप्ट में प्रोग्रामेटिक रूप से अपने नवीनतम संस्करण में है, तो आप कैसे जांचें कि वह सही है या गलत?

मैं इस तरह से एक स्क्रिप्ट के साथ देख सकते हैं:

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

या कमांड लाइन के साथ:

(base) C:\User>pip search gekko
gekko (0.2.3)  - Machine learning and optimization for dynamic systems
  INSTALLED: 0.2.3 (latest)

लेकिन मैं प्रोग्रामेटिक रूप से कैसे जांच करूं और सही या गलत लौटाऊं?


फास्ट संस्करण (केवल पैकेज की जाँच)

यह एक अनुपलब्ध संस्करण के साथ पैकेज को कॉल करने की ट्रिक करता है जैसे कि pip install package_name==random और प्रतिक्रिया सभी उपलब्ध संस्करण देता है, फिर प्रोग्राम नवीनतम को पढ़ता है।

फिर यह pip show package_name चलाता है और पैकेज का वर्तमान संस्करण प्राप्त करता है।

यदि यह एक मैच पाता है, तो यह सही है, अन्यथा गलत है

यह एक विश्वसनीय विकल्प है जिसे यह 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

यह एक pip list --outdated लिए कहता है - 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

नवीनतम संस्करण:

मेरे प्रोजेक्ट luddite में यह सुविधा है:

>>> import luddite
>>> luddite.get_version_pypi("gekko")
'0.2.3'

स्थापित संस्करण:

स्थापित संस्करण की जांच करने के लिए विहित तरीका शीर्ष स्तर के नामस्थान की __version__ विशेषता तक पहुंचने के लिए है:

>>> import gekko
>>> gekko.__version__
'0.2.0'

दुर्भाग्य से सभी परियोजनाओं ने इस विशेषता को निर्धारित नहीं किया है। जब वे नहीं करते हैं, तो आप मेटाडेटा से इसे खोदने के लिए pkg_resources का उपयोग कर सकते हैं:

>>> import pkg_resources
>>> pkg_resources.get_distribution("gekko").version
'0.2.0'

यह डेमो उद्देश्यों के लिए कम से कम चाल करना चाहिए। बस कॉल करें। आप जिस पैकेज की जांच करना चाहते हैं, उसके नाम के साथ isLatestVersion करें। यदि आप इसे कहीं महत्वपूर्ण उपयोग कर रहे हैं, तो आप url के अनुरोध को पकड़ना / पकड़ना चाहेंगे क्योंकि इंटरनेट का उपयोग उपलब्ध नहीं हो सकता है। यह भी ध्यान दें कि यदि पैकेज स्थापित नहीं है, तो isLatestVersion गलत हो जाएगा।

यह पायथन 3.7.4 और पिप 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

PyPI API को क्वेरी करके एक सरल स्क्रिप्ट को लिखना मुश्किल नहीं है । नवीनतम पायथन 3.8 के साथ, यह केवल मानक पुस्तकालय (जब पायथन 3.7 या अधिक पुराने का उपयोग करके संभव है, तो आपको importlib_metadata बैकपोर्ट स्थापित करना 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)

उपयोग उदाहरण:

$ python check_version.py setuptools
package: setuptools installed: 41.2.0 latest: 41.6.0

यदि आप packaging स्थापित करते हैं, तो यह संस्करण पार्सिंग के लिए distutils.version बेहतर विकल्प है:

from distutils.version import LooseVersion

...

LooseVersion(s)

हो जाता है

from packaging.version import parse

...

parse(s)




gekko