PIP封装安装两次(pip installs package twice)

2019-10-20 04:01发布

不幸的是我不能复制,但我们已经看到了好几次:

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

Answer 1:

这应该工作:

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


Answer 2:

我用这个方法来检查是否安装了两次包:

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(),它支持压缩蛋



Answer 3:

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的很旧版本能够安装同一个库的几个版本,并标记其中一个作为活跃的 ,但如果我没有记错提到的功能是前下降了好几年了。



文章来源: pip installs package twice