रनटाइम पर पायथन मॉड्यूल संस्करण की जाँच करना


118

कई तीसरे पक्ष के पायथन मॉड्यूल में एक विशेषता होती है जो मॉड्यूल के लिए संस्करण की जानकारी रखती है (आमतौर पर ऐसा कुछ module.VERSIONया जैसा module.__version__), हालांकि कुछ नहीं करते हैं।

ऐसे मॉड्यूल के विशेष उदाहरण libxslt और libxml2 हैं।

मुझे यह जांचने की आवश्यकता है कि इन मॉड्यूल के सही संस्करण का उपयोग रनटाइम पर किया जा रहा है। क्या इसे करने का कोई तरीका है?

एक संभावित समाधान को रनटाइम पर स्रोत में पढ़ा जाना चाहिए, इसे हैश करें, और फिर इसकी तुलना ज्ञात संस्करण के हैश से करें, लेकिन यह बुरा है।

क्या कोई बेहतर उपाय है?

जवाबों:


8

मैं हैशिंग से दूर रहूँगा। उपयोग किए जा रहे libxslt के संस्करण में कुछ प्रकार के पैच शामिल हो सकते हैं जो आपके उपयोग को प्रभावित नहीं करते हैं।

एक विकल्प के रूप में, मैं सुझाव देना चाहता हूं कि आप रन टाइम पर जांच न करें (यह नहीं जानते कि यह एक कठिन आवश्यकता है या नहीं)। अजगर सामान के लिए मैं लिखता हूं जिसमें बाहरी निर्भरताएं (3 पार्टी लाइब्रेरी) हैं, मैं एक स्क्रिप्ट लिखता हूं जो उपयोगकर्ता अपने अजगर की जांच करने के लिए चला सकते हैं यह देखने के लिए कि क्या मॉड्यूल के उपयुक्त संस्करण स्थापित हैं।

उन मॉड्यूल के लिए जिनके पास एक परिभाषित 'संस्करण' विशेषता नहीं है, आप उन इंटरफ़ेस (कक्षाओं और विधियों) का निरीक्षण कर सकते हैं और देख सकते हैं कि क्या वे उस इंटरफ़ेस से मेल खाते हैं जिसकी वे अपेक्षा करते हैं। फिर जिस वास्तविक कोड पर आप काम कर रहे हैं, मान लें कि 3 पार्टी मॉड्यूल में आपके द्वारा अपेक्षित इंटरफ़ेस है।


244

Pkg_resources का उपयोग करें । कम से कम PyPI से इंस्टॉल की गई कोई भी संस्करण संख्या होनी चाहिए।

>>> import pkg_resources
>>> pkg_resources.get_distribution("blogofile").version
'0.7.1'

8
यह भी ध्यान दें कि, पैकेज का नाम PyPI प्रविष्टि का होना चाहिए। तो कुछ ऐसा है जैसे "pkg_resources.get_distribution ('MySQLdb')। संस्करण" काम नहीं करेगा लेकिन "pkg_resources.get_distribution ('mysql-python') संस्करण" होगा।
राहुल

1
यदि आप एक पूर्ण फ़ाइल नाम के साथ चल रहे हैं, तो pkg_resourcesएक भिन्न संस्करण उठा सकते हैं , जिसे आप वास्तव में चला रहे हैं क्योंकि यह आपके PYTHONPATHया इससे मिलते-जुलते उदाहरण हैं ।
ट्रिपलए

4
यदि कोई व्यक्ति यह जानना चाहता है कि __version__विशेषता कैसे बनाई जाए : stackoverflow.com/q/17583443/562769
मार्टिन थोमा

pkg_resourcesलिंक एक त्रुटि 404 है
gerrit

स्वचालित प्रसंस्करण के लिए, यह प्रश्न
gerrit

6

कुछ विचार:

  1. उन फ़ंक्शन के लिए जाँच करें जो आपके आवश्यक संस्करणों में मौजूद हैं या मौजूद नहीं हैं।
  2. यदि कोई फ़ंक्शन अंतर नहीं हैं, तो फ़ंक्शन तर्क और हस्ताक्षर का निरीक्षण करें।
  3. यदि आप इसे फ़ंक्शन हस्ताक्षरों से समझ नहीं पाते हैं, तो आयात समय पर कुछ स्टब कॉल सेट करें और उनके व्यवहार की जांच करें।

संकुल को अपना संस्करण निर्दिष्ट करना चाहिए। ये विचार आम तौर पर 99% मामलों के लिए पूरी तरह से ओवरकिल होते हैं।
ज़ेल्फिर कल्टस्टल

2

आप उपयोग कर सकते हैं

pip freeze

आवश्यकताओं के प्रारूप में स्थापित संकुल को देखने के लिए।


1

आप इसके लिए importlib_metadataपुस्तकालय का उपयोग कर सकते हैं ।

यदि आप अजगर <पर हैं 3.8, तो पहले इसे स्थापित करें:

pip install importlib_metadata

अजगर के बाद से 3.8यह अजगर के मानक पुस्तकालय में शामिल है।

फिर, पैकेज के संस्करण की जांच करने के लिए (इस उदाहरण में lxml) रन:

>>> from importlib_metadata import version
>>> version('lxml')
'4.3.1'

ध्यान रखें कि यह केवल PyPI से स्थापित पैकेजों के लिए काम करता है। इसके अलावा, आपको पैकेज के नाम को versionविधि के तर्क के रूप में पारित करना होगा , बजाय कि एक मॉड्यूल नाम के जो यह पैकेज प्रदान करता है (हालांकि वे आमतौर पर समान होते हैं)।


0

मैं यह काफी अविश्वसनीय (सबसे अच्छा एक सहित उपलब्ध विभिन्न उपकरणों का उपयोग करने के लिए मिला pkg_resourcesने उल्लेख किया यह अन्य जवाब ), के रूप में उनमें से ज्यादातर सभी मामलों को कवर नहीं है। उदाहरण के लिए

  • अंतर्निहित मॉड्यूल
  • मॉड्यूल स्थापित नहीं है, लेकिन सिर्फ अजगर पथ में जोड़ा जाता है (उदाहरण के लिए आपकी आईडीई द्वारा)
  • उपलब्ध समान मॉड्यूल के दो संस्करण (एक स्थापित किए गए अजगर पथ में एक)

चूँकि हमें किसी भी पैकेज, मॉड्यूल या सबमॉड्यूल के संस्करण को प्राप्त करने के लिए एक विश्वसनीय तरीके की आवश्यकता थी , इसलिए मैंने लेखन की समाप्ति को समाप्त कर दिया । यह उपयोग करने के लिए काफी सरल है:

from getversion import get_module_version
import foo
version, details = get_module_version(foo)

देखें प्रलेखन जानकारी के लिए।


0

मॉड्यूल के लिए जो __version__निम्नलिखित प्रदान नहीं करता है वह बदसूरत है लेकिन काम करता है:

#!/usr/bin/env python3.6
import sys
import os
import subprocess
import re

sp = subprocess.run(["pip3", "show", "numpy"], stdout=subprocess.PIPE)
ver = sp.stdout.decode('utf-8').strip().split('\n')[1]
res = re.search('^Version:\ (.*)$', ver)
print(res.group(1))

या

#!/usr/bin/env python3.7
import sys
import os
import subprocess
import re

sp = subprocess.run(["pip3", "show", "numpy"], capture_output=True)
ver = sp.stdout.decode('utf-8').strip().split('\n')[1]
res = re.search('^Version:\ (.*)$', ver)
print(res.group(1))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.