为什么使用 Pyfakefs 时 Path.rename 出现 FileNotFoundError 错误?

发布于 2025-01-18 10:28:37 字数 1401 浏览 0 评论 0原文

我为一个函数编写了一个测试,该函数将文件从 /videos/vid_youtube.mp4 重命名为 /videos/youtube/vid.mp4。该测试使用 Pyfakefs 修补 fs。

当代码实际重命名文件时,我收到此错误。

FileNotFoundError: [Errno 2] No such file or directory: '/home/user/code/project/test/DLV/videos/vid_youtube.mp4' -> '/home/user/code/project/test/DLV/videos/youtube/vid.mp4'

这就是我设置 fakefs

def setUp(self) -> None:
    self.setUpPyfakefs()
    self.fs.create_dir(Path(Dirs.VIDEOS))  # /home/user/code/project/test/DLV/videos
    self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))

测试的代码。

class Files:
    @staticmethod
    def rename_video_files():
        all_files = Collect.video_files()

        for files_for_type in all_files:
            for file in all_files[files_for_type]:
                path = Path(file)
                platform = Files.detect_platform(path)
                platform_dir = Path(Dirs.VIDEOS, platform)
                platform_dir.mkdir(exist_ok=True)

                new_name = path.stem.replace(f'_{platform}', '')
                new_path = Dirs.VIDEOS / platform / f'{new_name}{path.suffix}'

                old_path = Dirs.VIDEOS / path
                old_path.rename(new_path)   # throws FileNotFoundError

我调试了测试和被测方法,甚至将假文件传递给 rename_video_files(fakefs) 来检查文件和目录。所有文件和目录看起来都是正确的。

这里出了什么问题?

I wrote a test for a function that renames files from e.g. /videos/vid_youtube.mp4 to /videos/youtube/vid.mp4. The test patches the fs with Pyfakefs.

When the code actually renames the file, I get this error.

FileNotFoundError: [Errno 2] No such file or directory: '/home/user/code/project/test/DLV/videos/vid_youtube.mp4' -> '/home/user/code/project/test/DLV/videos/youtube/vid.mp4'

This is how I set up fakefs

def setUp(self) -> None:
    self.setUpPyfakefs()
    self.fs.create_dir(Path(Dirs.VIDEOS))  # /home/user/code/project/test/DLV/videos
    self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))

The code under test.

class Files:
    @staticmethod
    def rename_video_files():
        all_files = Collect.video_files()

        for files_for_type in all_files:
            for file in all_files[files_for_type]:
                path = Path(file)
                platform = Files.detect_platform(path)
                platform_dir = Path(Dirs.VIDEOS, platform)
                platform_dir.mkdir(exist_ok=True)

                new_name = path.stem.replace(f'_{platform}', '')
                new_path = Dirs.VIDEOS / platform / f'{new_name}{path.suffix}'

                old_path = Dirs.VIDEOS / path
                old_path.rename(new_path)   # throws FileNotFoundError

I debugged the test and the method under test and even passed the fake fs to rename_video_files(fakefs) to inspect the files and directories. All files and directories look correct.

What is going wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哆啦不做梦 2025-01-25 10:28:37

这里的问题很可能是dirs.videos的静态初始化。这是在加载时间初始化为pathlib.path的初始化,并且在您设置时将不会修补unitTest.patch用于修补)。

有两种解决此问题的方法:

  • 调整代码以不初始化路径stat上
    的初始化
    这可以通过静态定义str路径,然后在运行时将其转换为path,或者使用方法来获取路径而不是属性(例如dirs.video()而不是dirs.video`)。
  • 调整测试以重新加载测试的代码
    如果在pyfakefs之后重新加载了测试的代码,则将正确修补它。 pyfakefs提供setUppyFakefs执行此操作:(
from pyfakefs.fake_filesystem_unittest import TestCase

from my_module import video_files
from my_module.video_files import Dirs, Files


class MyTest(TestCase):
    def setUp(self) -> None:
        self.setUpPyfakefs(modules_to_reload=[video_files])
        self.fs.create_dir(
            Path(Dirs.VIDEOS))  # /home/user/code/project/test/DLV/videos
        self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))

测试的代码位于my_module.video_files.py.py )中

在假设下,您正在 br>
我是Pyfakefs的贡献者。

The problem here is most likely the static initialization of Dirs.VIDEOS. This is initialized at load time as a pathlib.Path, and won't be patched later at the time you setup pyfakefs (the same problem would happen if you where to use unittest.patch for patching).

There are two ways to fix this:

  • adapt the code to not initialize the path statically
    This could be done by statically defining the str path, and converting it to a Path at run time, or by using a method to get the path instead of an attribute (e.g. Dirs.VIDEO() instead of Dirs.VIDEO`).
  • adapt the test to reload the tested code
    If reloading the tested code after pyfakefs has been initialized, it will be correctly patched. pyfakefs provides an argument in setUpPyfakefs that does that:
from pyfakefs.fake_filesystem_unittest import TestCase

from my_module import video_files
from my_module.video_files import Dirs, Files


class MyTest(TestCase):
    def setUp(self) -> None:
        self.setUpPyfakefs(modules_to_reload=[video_files])
        self.fs.create_dir(
            Path(Dirs.VIDEOS))  # /home/user/code/project/test/DLV/videos
        self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))

(under the assumption, that your code under test is located in my_module.video_files.py)

Disclaimer:
I'm a contributor to pyfakefs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文