不幸的是我不能复制,但我们已经看到了好几次:
PIP两次安装一个软件包。
如果卸载第一个,第二个获得可见并可得到卸载了。
我的问题:我如何使用python检查是否安装了两次包?
背景:我想写一个测试,检查该(devOp)
更新
- 软件包安装在一个virtualenv中。
- 这两个包有不同的版本。
- 这不是一个手工解决这一解决方案的一个副本。 我寻找一个解决方案与Python代码来检测这一点。 如何解决这不是如果我的问题的一部分。
更新2
命令pip freeze
输出包只有一次:
pip freeze | grep -i south
South==0.8.1
但是在虚拟ENV存在两次:
find lib -name top_level.txt |xargs cat | grep -i south
south
south
ls lib/python2.7/site-packages/| grep -i south
south
South-0.8.1-py2.7.egg
South-0.8.4-py2.7.egg-info
这应该工作:
def count_installs(pkg_name):
import imp, sys
n = 0
for location in sys.path:
try:
imp.find_module(pkg_name, [location])
except ImportError: pass
else: n += 1
return n
如
>>> count_installs("numpy")
2
>>> count_installs("numpyd")
0
>>> count_installs("sympy")
1
我用这个方法来检查是否安装了两次包:
def test_pip_python_packages_installed_twice(self):
# https://stackoverflow.com/a/23941861/633961
pkg_name_to_locations=defaultdict(set)
for dist in pkg_resources.working_set:
for pkg_name in dist._get_metadata('top_level.txt'):
for location in sys.path:
try:
importutils.does_module_exist_at_given_path(pkg_name, [location])
except ImportError:
continue
if location.startswith('/usr'):
# ignore packages from "root" level.
continue
pkg_name_to_locations[pkg_name].add(location)
errors=dict()
for pkg_name, locations in sorted(pkg_name_to_locations.items()):
if pkg_name in ['_markerlib', 'pkg_resources', 'site', 'easy_install', 'setuptools', 'pip']:
continue
if len(locations)==1:
continue
errors[pkg_name]=locations
self.assertFalse(errors,
'Some modules are installed twice:\n%s' % '\n'.join(['%s: %s' % (key, value) for key, value in sorted(errors.items())]))
importutils
def does_module_exist_at_given_path(module_name, path):
'''
imp.find_module() does not find zipped eggs.
Needed for check: check if a package is installed twice.
'''
for path_item in path:
result=None
try:
result=imp.find_module(module_name, [path_item])
except ImportError:
pass
if result:
return bool(result)
if not os.path.isfile(path_item):
continue
# could be a zipped egg
module=zipimport.zipimporter(path_item).find_module(module_name)
if module:
return bool(module)
raise ImportError(module_name)
相关: imp.find_module(),它支持压缩蛋
South-0.8.1-py2.7.egg
是南源代码zip压缩包, South-0.8.4-py2.7.egg-info
是与南库的元数据文件的目录。
.egg-info
(从建库.tar.gz
)或.dist-info
(从车轮安装库.whl
)都存在通过安装在每台库pip
。
.egg
如果库标记为档案创建zip_safe
在(元数据setup(zip_safe=True)
在setup.py
)。 否则PIP使得用提取的Python源文件的目录。
setuptools的很旧版本能够安装同一个库的几个版本,并标记其中一个作为活跃的 ,但如果我没有记错提到的功能是前下降了好几年了。