Python 2.6 : os. rename() 或 os.renames() 报告 OSError 但文件名为 None

标签 python posix python-2.6

如果您调用 os.rename提供不存在的文件或目录,OSError通过将其设置为 None 来忽略文件名.这是 2.6 中的错误,已在某些更高版本中修复?

您只需执行以下操作即可重现该问题:

python -c 'import os ; os.rename("/tmp/abc", "/tmp/cba")'

哪里都不/tmp/abc也不/tmp/cba存在。

我只是想知道是否应该为 os.rename 实现一个包装器以拦截 OSError 并在重新发送错误之前更正文件名属性。

更新

我实现了一个简单的测试包装器,它产生了所需的行为:

$ /tmp/osrename.py
Traceback (most recent call last):
File "/tmp/osrename.py", line 26, in <module>
  os.rename('/tmp/abc', '/tmp/cba')
File "/tmp/osrename.py", line 8, in __os_rename
  os_rename(a, b)
OSError: [Errno 2] No such file or directory: '/tmp/abc'

实现如下:

import os, sys

def __os_rename_wrapper(os_rename):
    def __os_rename(a, b):
        try:
            os_rename(a, b)

        except OSError:
            exc = sys.exc_info()[1]

            if getattr(exc, 'filename', None) is None:
                exc.filename = "{0} -> {1}".format(repr(a), repr(b))

            raise

    __os_rename.__name__ = os_rename.__name__
    __os_rename.__doc__ = os_rename.__doc__

    return __os_rename

os.rename = __os_rename_wrapper(os.rename)


os.rename('/tmp/abc', '/tmp/cba')

有没有办法 Hook 模块加载,以便可以动态应用这些修复?

最佳答案

在 python 2.7.8 中也发生了同样的情况,所以我猜这是故意的。

但是:

在 python 3.4 中,第二个属性 filename2 被添加到 OSError,如 @Random832 所述并且属性设置正确。

PEP 3151可能会有所启发,特别是:

Since WindowsError is coalesced into OSError, the latter gains a winerror attribute under Windows. It is set to None under situations where it is not meaningful, as is already the case with the errno , filename and strerror attributes (for example when OSError is raised directly by Python code).

及以下:

In order to preserve useful compatibility , these subclasses should still set adequate values for the various exception attributes defined on the superclass (for example errno , filename , and optionally winerror ).

PEP 被标记为 3.3 版已接受。 此外 3.3 文档说:

For exceptions that involve a file system path (such as open() or os.unlink()), the exception instance will contain an additional attribute, filename, which is the file name passed to the function.

目前还不清楚该属性是针对哪些函数设置的,但基于以上我会说重命名函数肯定涉及文件名,因此应该设置文件名属性。

如果您发现与此相关的任何其他 PEP,请随时添加。

目前我能想到的唯一原因是在重命名函数中你使用了两个文件名,所以可能不清楚在异常文件名属性上设置哪个文件名(对此有什么想法吗?)。

如果您需要设置值,您关于属性更正的解决方案是可行的,至少在我看来是这样。

关于Python 2.6 : os. rename() 或 os.renames() 报告 OSError 但文件名为 None,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29970378/

相关文章:

c - 设置读取 stdin 的超时时间

c - 在 C 中处理 POSIX - 错误消息 : Segmentation Fault (core dumped)

python - 连接到运行 Python 脚本的 Raspberry Pi 的磁性门传感器报告误报

python - 正确的xpath是什么?

java - 通过 Jython 使用 .pyc 文件

c - 为什么 `aio_write` 不允许并发缓冲区访问?

python - 检查数字 (mod 2) 是否有余数 0 的函数不起作用

Python的列表理解和其他更好的实践

python unittest2 - 将测试方法名称暴露给设置方法

python - 如何在 Python 中分割输入参数