简体   繁体   English

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

[英]Python 2.6: os.rename() or os.renames() reports OSError but filename is None

If you call os.rename providing files or directories that do not exist, the OSError that is raised omits the filename by setting it to None . 如果调用os.rename提供不存在的文件或目录,则引发的OSError通过将文件名设置为None来忽略文件名。 Is this a bug in 2.6 that has been fixed in some later version? 这是2.6中的错误,已在某些更高版本中修复吗?

You can reproduce the issue by simply doing: 您只需执行以下操作即可重现该问题:

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

Where neither /tmp/abc nor /tmp/cba exist. /tmp/abc/tmp/cba都不存在的地方。

I am just wondering if I should implement a wrapper to os.rename to intercept OSError and correct the filename attribute before resending the error. 我只是想知道是否应该在重发错误之前对os.rename实现一个包装程序以拦截OSError并更正filename属性。

Update 更新资料

I implemented a simple test wrapper, which produces the desired behaviour: 我实现了一个简单的测试包装器,该包装器产生了所需的行为:

$ /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'

Here is the implementation: 这是实现:

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')

Is there a way to hook module loading so that these sort of fixes can be applied dynamically? 有没有办法挂接模块加载,以便可以动态应用这些修复程序?

The same happens in python 2.7.8 so I guess that it was intentional. 在python 2.7.8中也发生了同样的事情,所以我想这是故意的。

BUT: 但:

In python 3.4 a second attribute filename2 was added to OSError as stated by @Random832 and the attributes are set correctly. 在Python 3.4中,如@ Random832所述,第二个属性filename2已添加到OSError,并且属性设置正确。

This PEP 3151 may shed a bit of light, in particular: PEP 3151可能会有所启发 ,特别是:

Since WindowsError is coalesced into OSError, the latter gains a winerror attribute under Windows. 由于WindowsError已合并为OSError,因此OSError在Windows下获得了winerror属性。 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). 在没有意义的情况下(例如,使用errno,filename和strerror属性的情况下)(例如,当OSError由Python代码直接引发时),将其设置为None。

and below: 及以下:

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 ). 为了保持有用的兼容性,这些子类仍应为在超类上定义的各种异常属性(例如errno,filename和可选的winerror)设置足够的值。

The PEP is marked as accepted for version 3.3. PEP被标记为版本3.3接受。 Moreover 3.3 docs says: 此外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. 对于涉及文件系统路径的异常(例如open()或os.unlink()),异常实例将包含一个附加属性filename,这是传递给函数的文件名。

It isn't exactly clear for which functions the attribute is set but based on the above I would say that the rename function definitely involves a file name, and therefore the filename attribute should be set. 目前尚不清楚为哪个功能设置属性,但基于以上内容,我会说重命名功能肯定包含文件名,因此应设置filename属性。

If you find any other PEP regarding this, feel free to add it. 如果您发现与此有关的任何其他PEP,请随时添加。

The only reason I can think of at the moment is that in the rename function you use two file names, so it might be unclear which one to set on the exception filename attribute (any thoughts about this?). 我目前能想到的唯一原因是,在重命名功能中,您使用了两个文件名,因此可能不清楚在异常文件名属性上设置哪个文件名(对此有何想法?)。

Your solution regarding the correction of the attribute is doable if you need the value to be set, at least in my opinion. 如果您需要设置值,那么至少在我看来,有关属性校正的解决方案是可行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM