Python pip安装包两次

Python pip安装包两次,python,package,pip,virtualenv,Python,Package,Pip,Virtualenv,不幸的是,我无法复制它,但我们已经多次看到它: pip安装一个包两次 如果卸载第一个,第二个将可见,也可以卸载 我的问题:如果一个包安装了两次,如何使用python进行检查 背景:我想写一个测试来检查这个(devOp) 更新 软件包安装在virtualenv中 这两个包有不同的版本 这不是手动解决此问题的解决方案的副本。我用python代码搜索一个解决方案来检测这一点。如何解决这个问题不是我的问题的一部分 更新2 命令pip freeze仅输出包一次: pip freeze | grep -

不幸的是,我无法复制它,但我们已经多次看到它:

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

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
安装的每个库都存在

如果库在元数据中标记为
zip\u-safe
setup(zip\u-safe=True)
in
setup.py
),则创建
.egg
存档。 否则,pip将使用提取的python源文件创建一个目录

非常旧版本的setuptools能够安装同一个库的多个版本,并将其中一个标记为活动,但如果我没记错的话,所提到的功能在多年前就被删除了。

这应该可以:

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


我使用此方法检查包是否安装了两次:

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())]))
重要事项

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)

相关:

这个问题可能会帮助您解决这个问题:它们是不同的版本吗?一个安装在全球,另一个安装在你的虚拟机上吗?@guettli很遗憾,你不能复制它。这很有效。非常感谢你。A编写了一个单元测试,它在工作集中的所有包上循环。见下文。
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)