“警告conda.gateways.disk:exp_backoff_fn(47):在”conda安装“期间,使用errno 41”未捕获退避“

时间:2017-01-14 18:42:56

标签: python warnings conda

从今天开始,我得到了很多

  

警告conda.gateways.disk:exp_backoff_fn(47):使用errno 41进行未审核的退避

当我尝试使用conda installconda update更新或安装软件包时出现

警告。例如:

(...) C:\Users\...> conda install numba
Fetching package metadata ...........
Solving package specifications: .

Package plan for installation in environment C:\...:

The following packages will be DOWNGRADED due to dependency conflicts:

    numba: 0.30.0-np111py35_0 --> 0.30.1-np111py35_0

Proceed ([y]/n)? y

numba-0.30.0-np111p35_0 100% |###############################| Time: 0:00:00   2.50 MB/s
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41

之后安装了软件包,但所有这些警告似乎表明某些内容无法正常运行。

OS: Windows 10 64 bit
conda: 4.3.4

你能说出我需要做些什么来修复这些警告吗?或者我可以忽略它们吗?

2 个答案:

答案 0 :(得分:14)

您看到的这些警告是"正常"根据目前的conda源码树。 为了理解上述警告的起源,让我们看看问题中的源代码和conda存储库中的最近提交(https://github.com/conda/conda)。 打印您看到的警告的相关源代码如下:

https://github.com/conda/conda/blob/4.3.4/conda/gateways/disk/init.py

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

import sys
from errno import EACCES, ENOENT, EPERM, EPROTOTYPE
from logging import getLogger
from os.path import basename
from time import sleep

from ...common.compat import on_win

log = getLogger(__name__)

MAX_TRIES = 7


def exp_backoff_fn(fn, *args, **kwargs):
    """Mostly for retrying file operations that fail on Windows due to virus scanners"""
    max_tries = kwargs.pop('max_tries', MAX_TRIES)
    if not on_win:
        return fn(*args, **kwargs)

    import random
    # with max_tries = 6, max total time ~= 3.2 sec
    # with max_tries = 7, max total time ~= 6.5 sec
    for n in range(max_tries):
        try:
            result = fn(*args, **kwargs)
        except (OSError, IOError) as e:
            log.trace(repr(e))
            if e.errno in (EPERM, EACCES):
                if n == max_tries-1:
                    raise
                sleep_time = ((2 ** n) + random.random()) * 0.1
                caller_frame = sys._getframe(1)
                log.trace("retrying %s/%s %s() in %g sec",
                          basename(caller_frame.f_code.co_filename),
                          caller_frame.f_lineno,
                          fn.__name__,
                          sleep_time)
                sleep(sleep_time)
            elif e.errno in (ENOENT, EPROTOTYPE):
                # errno.ENOENT File not found error / No such file or directory
                # errno.EPROTOTYPE OSError(41, 'The directory is not empty')
                raise
            else:
                log.warn("Uncaught backoff with errno %d", e.errno)
                raise
        else:
            return result

从上面的源代码中,它似乎是Windows上出现的警告,可能会在

时出现
  

由于病毒扫描程序而重试在Windows上失败的文件操作

使用https://msdn.microsoft.com/en-us/library/t3ayayh1.aspx进入细节,似乎 errno 41 对应

  

ENOTEMPTY:目录不为空

表示指定的目录不为空。 这是一个未被捕获的错误,因为他们没有处理此类错误的分支( ENOTEMPTY ),而例如他们遇到了另一个错误,例如< em> EPERM 或 EACCES 在提交https://github.com/conda/conda/commit/fb2a783d9b9371559b5ea82aaf8ae631c2ce0450#diff-3757ed9862260ae3b54768b3e482e3fe中 他们明确将报告EPROTOTYPE删除为OSError(41, 'The directory is not empty'),现在您可以在

中看到错误编号报告为警告
log.warn("Uncaught backoff with errno %d", e.errno)

他们修改的另一部分是https://github.com/conda/conda/blob/fb2a783d9b9371559b5ea82aaf8ae631c2ce0450/conda/gateways/disk/delete.py,在delete_trash()函数中,所以现在,如果要启用信息日志,很可能会看到像

这样的行
  

&#34;无法完全清除垃圾箱目录%s \ n剩余%d个文件。&#34;

启用

log.info("Unable to fully clean trash directory %s\nThere are %d remaining file(s).",
                 trash_dir, len(files_remaining))  

现在,您引用(安装,更新)的命令调用delete_trash()
https://github.com/conda/conda/blob/f4b386476307e3979679957292d4f6e4c581df03/conda/cli/main_install.py
https://github.com/conda/conda/blob/a26b1eff17dcaf12f03aea5bbe8dee1e01308de7/conda/cli/main_update.py

可以看出,delete_trash()分别在“安装”中被触发。并且&#39;更新&#39;以前分别由以下代码片段提到的文件:

from ..gateways.disk.delete import delete_trash

# some other code ...

def execute(args, parser):
    install(args, parser, 'install')
    delete_trash()

from ..gateways.disk.delete import delete_trash

# some other code ...

def execute(args, parser):
    install(args, parser, 'update')
    delete_trash()  
然后,

delete_trash()将通过backoff_rmdir()backoff_unlink()触发该代码路径,最终会导致您从exp_backoff_fn()看到的警告,如前所示。
因此,总而言之,主要的调用链是

update or install --> delete_trash() --> backoff_rmdir() or backoff_unlink() --> exp_backoff_fn() --> your warning message

根据在存储库中完成的源代码修改,开发人员认为这些警告可以安全地忽略,因为这些警告发生在&#34;清理&#34;更新或安装命令的阶段,即在已成功执行更新或安装操作之后 我无法100%说你可以放心地忽略这些警告。如果几次尝试后删除垃圾目录的命令成功,那么没问题。但如果它没有成功,那么你就会遇到这个目录由于没有删除它而变得越来越大的问题。回购中几乎没有问题,我不知道这些修补程序是否涵盖了你所遇到的代码路径。我的印象可能不是。要获得进一步的见解,您可以激活信息日志级别。

更新:此问题https://github.com/conda/conda/issues/4164完全提及您报告的警告,因为由于所有重试,人们获得了更长的更新和安装时间。正如我所提到的那样,在所有重试(指数退避)之后,删除操作可能成功或失败,该人也在其报告中提到了这一方面。
正如你在这里看到的那样 https://github.com/conda/conda/issues/3664
由于重试,人们用很少的黑客来解决等待时间长的问题,并且还会在没有警告的情况下进行下一次命令conda install Xconda update X。这些建议是:

  1. (加快重试/删除时间)在conda/gateways/disk/init.py
  2. 副本中设置MAX_TRIES = 1
  3. 在运行下一个conda install Xconda update X之前删除.trash目录。有关某些人使用简单脚本自动删除该目录的解决方法,请参阅https://github.com/conda/conda/issues/3664。通常这应该是安全的。
  4. 所以问题的答案是:
    1)您可以使用https://github.com/conda/conda/issues/3664中提到的解决方法,它使用以下powershell脚本(和另一个脚本):

    $cir = conda info --root
    $trash_dir = "$($cir)\pkgs\.trash"
    if (Test-Path $trash_dir){
        Remove-Item -Recurse -Force $trash_dir
    }
    conda --debug update --all --yes --quiet 
    

    基本上清理.trash目录;

    2)您可以放心地忽略警告,因为它们不会影响功能;问题是,填充的.trash越多,删除项目的时间和重试次数就越多,这样就会遇到性能问题;正如你所提到的那样,它有&#34;泄漏&#34;但它并没有影响功能。该目录应该被清空并删除,因为它包含不再需要的垃圾。系统将尝试删除它,但可能无法执行此操作。所以使用1)。

    更新2 :正如我的一条评论中所述,其中一项重要更改位于conda/gateways/disk/__init__.py文件中,这是一个&#34;修复&#34; (https://github.com/conda/conda/commit/6cb3be39aec1c738678ae27b3a264941d08c859a)使其达到4.3.6版本的conda(conda 4.3.6 release info),解决了相关警告。
    没有看到警告的关键是通过一个明确捕获并处理之前解释的错误的分支。现在,当ENOTEMPTY类型的错误发生时(这是在这种情况下触发警告打印的错误),这将被捕获并且不会转到打印问题检查的警告的分支。 要了解主要差异,请在版本 4.3.4

    elif e.errno in (ENOENT, EPROTOTYPE):                   
         raise
    else:
         log.warn("Uncaught backoff with errno %d", e.errno)
         raise
    

    在版本 4.3.6 中变为:

    elif e.errno in (ENOENT, ENOTEMPTY):    
        raise
    else:
        log.warn("Uncaught backoff with errno %s %d", errorcode[e.errno], e.errno)
        raise
    

    并且您清楚地看到,现在该错误不会进入else分支,因此在这种情况下您不会看到该消息。

答案 1 :(得分:1)

我的计算机上出现了这些警告,包括conda版本4.3.4和4.3.5,但不再出现在4.2.x版本中,也没有出现在最新版本(4.3.6)中。

我想最好的方法来修复&#34;问题是更新conda:

$ conda update conda

或降级到4.2:

$ conda install conda=4.2

两个版本的警告都会消失。