pip安装包两次

时间:2014-05-16 14:14:58

标签: python package pip virtualenv

不幸的是我无法重现它,但我们已经多次看到它了:

  

pip安装一个包两次。

如果卸载第一个,则第二个可见,也可以卸载。

我的问题:如果包安装了两次,我如何检查python?

背景:我想写一个检查这个(devOp)

的测试

更新

  • 软件包安装在virtualenv中。
  • 这两个包有不同的版本。
  • 这不是手动解决这个问题的解决方案的重复。我搜索一个解决方案,用python代码检测它。如果我的问题,如何解决这个问题。

更新2

命令pip freeze仅输出一次包:

pip freeze | grep -i south
South==0.8.1

但是在虚拟环境中,它存在两次:

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

3 个答案:

答案 0 :(得分: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

e.g。

>>> count_installs("numpy")
2
>>> count_installs("numpyd")
0
>>> count_installs("sympy")
1

答案 1 :(得分: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() which supports zipped eggs

答案 2 :(得分:0)

South-0.8.1-py2.7.egg是一个包含 South 源代码的zip存档,South-0.8.4-py2.7.egg-info是一个包含 South 库元数据文件的目录。

对于由.egg-info安装的每个库,

.tar.gz(对于从.dist-info构建的库)或.whl(对于从pip安装的库)都存在。

如果库中的.egg标记为zip_safe setup(zip_safe=True),则会创建

setup.py存档。 否则 pip 会生成一个包含已提取的python源文件的目录。

非常旧版本的 setuptools 能够安装同一个库的多个版本,并将其中一个标记为活动,但是如果我已经删除多年前提到的功能回想一下。