# assuming 'path' holds the path to the file
import ast
with open(path, 'rU') as file:
t = compile(file.read(), path, 'exec', ast.PyCF_ONLY_AST)
for node in (n for n in t.body if isinstance(n, ast.Assign)):
if len(node.targets) == 1:
name = node.targets[0]
if isinstance(name, ast.Name) and \
name.id in ('__version__', '__version_info__', 'VERSION'):
v = node.value
if isinstance(v, ast.Str):
version = v.s
break
if isinstance(v, ast.Tuple):
r = []
for e in v.elts:
if isinstance(e, ast.Str):
r.append(e.s)
elif isinstance(e, ast.Num):
r.append(str(e.n))
version = '.'.join(r)
break
verstr = "unknown"
try:
verstrline = open('yourpackage/_version.py', "rt").read()
except EnvironmentError:
pass # Okay, there is no version file.
else:
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
mo = re.search(VSRE, verstrline, re.M)
if mo:
verstr = mo.group(1)
else:
raise RuntimeError("unable to find version in yourpackage/_version.py")
最后,在这样的 yourbasedir/yourpackage/__init__.py import _ version 中:
__version__ = "unknown"
try:
from _version import __version__
except ImportError:
# We're running in a tree that doesn't have a _version.py, so we don't know what our version is.
pass
这样做的一个代码示例是我维护的“ pyutil”包。(请参阅 PyPI 或 google search —— stackoverflow 不允许我在这个答案中包含指向它的超链接。)
version = '0.30.unknown'
with file('mypkg/mymod.py') as f:
for line in f:
if line.startswith('__version__'):
_, _, version = line.replace("'", '').split()
break
如果您希望格外小心并使用真正的解析器:
import ast
version = '0.30.unknown2'
with file('mypkg/mymod.py') as f:
for line in f:
if line.startswith('__version__'):
version = ast.parse(line).body[0].value.s
break
from itertools import ifilter
from os import path
from ast import parse
with open(path.join('package_name', '__init__.py')) as f:
__version__ = parse(next(ifilter(lambda line: line.startswith('__version__'),
f))).body[0].value.s
import pkg_resources
version_string = None
try:
if pkg_resources.working_set is not None:
disto_obj = pkg_resources.working_set.by_key.get('<my pkg name>', None)
# (I like adding ", None" to gets)
if disto_obj is not None:
version_string = disto_obj.version
except Exception:
# Do something
pass
VERSION = 0.0.0 python setup.py sdist bdist _ eler
在 setup.py 中
import os
setup(
version=os.environ['VERSION'],
...
)
为了与封装器版本的一致性检查,我使用下面的脚本。
PKG_VERSION=`python -c "import pkg; print(pkg.__version__)"`
if [ $PKG_VERSION == $VERSION ]; then
python setup.py sdist bdist_wheel
else
echo "Package version differs from set env variable"
fi
值得一提的是,我编写 获得版本是为了解决我们的一个项目需要的这个问题。它依赖于一系列符合 PEP 的策略来返回模块的版本,并为开发模式(git scm)添加一些策略。
例如:
from getversion import get_module_version
# Get the version of an imported module
from xml import dom
version, details = get_module_version(dom)
print(version)
投降
3.7.3.final.0
为什么会发现这个版本? 你可以从 details中了解到:
> print(details)
Version '3.7.3.final.0' found for module 'xml.dom' by strategy 'get_builtin_module_version', after the following failed attempts:
- Attempts for module 'xml.dom':
- <get_module_version_attr>: module 'xml.dom' has no attribute '__version__'
- Attempts for module 'xml':
- <get_module_version_attr>: module 'xml' has no attribute '__version__'
- <get_version_using_pkgresources>: Invalid version number: None
- <get_builtin_module_version>: SUCCESS: 3.7.3.final.0
import re
with open("setup.cfg", "r") as _file:
data = _file.read()
print(re.findall(r"\nversion(?:[\s]+|[\s])?[=](?:[\s]+|[\s])?(.*)", data))
# -> ['1.1.0']