[python] 런타임에 Python 모듈 버전 확인

많은 타사 Python 모듈에는 모듈에 대한 버전 정보를 보유하는 속성이 있지만 (일반적으로 module.VERSION또는 같은 것 module.__version__) 일부는 그렇지 않습니다.

이러한 모듈의 특정 예는 libxslt 및 libxml2입니다.

이러한 모듈의 올바른 버전이 런타임에 사용되고 있는지 확인해야합니다. 이를 수행하는 방법이 있습니까?

잠재적 인 해결책은 런타임에 소스를 읽고 해시 한 다음 알려진 버전의 해시와 비교하는 것입니다.

더 나은 솔루션이 있습니까?



답변

나는 해싱을 멀리 할 것입니다. 사용중인 libxslt 버전에는 사용에 영향을주지 않는 패치 유형이 포함될 수 있습니다.

대안으로 런타임에 확인하지 않는 것이 좋습니다 (어려운 요구 사항인지 아닌지 모르겠 음). 외부 종속성 (타사 라이브러리)이있는 내가 작성한 Python 항목의 경우 사용자가 Python 설치를 확인하여 적절한 버전의 모듈이 설치되어 있는지 확인할 수있는 스크립트를 작성합니다.

정의 된 ‘version’속성이없는 모듈의 경우 포함 된 인터페이스 (클래스 및 메서드)를 검사하고 예상하는 인터페이스와 일치하는지 확인할 수 있습니다. 그런 다음 작업중인 실제 코드에서 타사 모듈에 예상 한 인터페이스가 있다고 가정합니다.


답변

pkg_resources를 사용하십시오 . PyPI에서 설치된 모든 것은 적어도 버전 번호가 있어야합니다.

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


답변

몇 가지 아이디어 :

  1. 필요한 버전에 존재하거나 존재하지 않는 기능을 확인하십시오.
  2. 함수 차이가 없으면 함수 인수와 서명을 검사하십시오.
  3. 함수 시그니처에서 파악할 수없는 경우 가져올 때 일부 스텁 호출을 설정하고 동작을 확인하십시오.

답변

당신이 사용할 수있는

pip freeze

요구 사항 형식으로 설치된 패키지를 확인합니다.


답변

이를 위해 importlib_metadata라이브러리를 사용할 수 있습니다 .

python <을 사용하는 3.8경우 먼저 다음을 사용하여 설치하십시오.

pip install importlib_metadata

파이썬 이후 3.8로 파이썬의 표준 라이브러리에 포함되어 있습니다.

그런 다음 패키지의 버전을 확인하려면 (이 예에서는 lxml) 다음을 실행합니다.

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

이것은 PyPI에서 설치된 패키지에 대해서만 작동합니다. 또한 version이 패키지가 제공하는 모듈 이름이 아니라 패키지 이름을 메서드에 대한 인수로 전달해야 합니다 (대개 동일하지만).


답변

대부분의 경우 모든 경우를 다루지는 않기 때문에 사용 가능한 다양한 도구 ( 이 다른 답변에서pkg_resources 언급 한 가장 좋은 도구 포함)를 사용하는 것이 매우 불안정하다는 것을 알았습니다 . 예를 들면

  • 내장 모듈
  • 모듈이 설치되지 않았지만 Python 경로에 추가되었습니다 (예 : IDE에 의해)
  • 두 가지 버전의 동일한 모듈 사용 가능 (하나는 설치된 것을 대체하는 Python 경로에 있음)

우리의 버전을 얻을 수있는 신뢰할 수있는 방법이 필요하기 때문에 어떤 패키지, 모듈 또는 서브 모듈을, 내가 쓰기 결국 하는 getVersion . 사용하기 매우 간단합니다.

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

자세한 내용은 설명서 를 참조하십시오.


답변

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