簡體   English   中英

如何將 pyfakefs 與 importlib.resources.path 結合使用

[英]How to use pyfakefs in conjunction with importlib.resources.path

給定一些已安裝的包,以下代碼可用於打印其在文件系統上的位置:

import importlib.resources

def print_package_path():
    with importlib.resources.path("importlib", "") as path:
        print(path)

if __name__ == "__main__":
    print_package_path()  # /home/me/python_3.8/lib/python3.8/importlib on my machine

如果我想測試一個包含pytest作為測試套件和pyfakefs以在測試期間偽造文件系統的語句的函數,它將崩潰並出現令人困惑的錯誤( IsADirectoryError: [Errno 21] Is a directory on ubuntu and PermissionError: [Errno 13] Permission denied Windows 上的PermissionError: [Errno 13] Permission denied )- 甚至不需要對fs固定裝置做任何事情,它只需要在代碼運行時就在那里。

pytest執行這個函數

def test_package_path(fs):
    print_package_path()

會導致

______________________________ test_package_path _______________________________

fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x7f84f2996910>

    def test_package_path(fs):
>       print_package_path()

/home/me/foo.py:11: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/home/me/foo.py:4: in print_package_path
    with importlib.resources.path("importlib", "") as path:
/home/me/pythons/python_3.8/lib/python3.8/contextlib.py:113: in __enter__
    return next(self.gen)
/home/me/venv/lib/python3.8/importlib/resources.py:201: in path
    with open_binary(package, resource) as fp:
/home/me/venv/lib/python3.8/importlib/resources.py:91: in open_binary
    return reader.open_resource(resource)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_frozen_importlib_external.SourceFileLoader object at 0x7f84f7527370>
resource = ''

>   ???
E   IsADirectoryError: [Errno 21] Is a directory: '/home/me/venv/lib/python3.8/importlib'

<frozen importlib._bootstrap_external>:988: IsADirectoryError

這對我來說是零意義的。 目錄應該從一開始就不能用作資源嗎?

我必須承認我並不真正理解importlib.resources模塊,所以我可能只是使用錯誤(我的實際用例是在開發過程中創建一個文件,並避免使用__file__來找到正確的位置)。

請參閱pyfakefs 文檔,其中指出:

出於多種原因,模塊可能無法與 pyfakefs 一起使用。 pyfakefs 通過修補一些文件系統相關的模塊和功能來工作,特別是:

  • os 和 os.path 模塊中的大多數文件系統相關函數
  • 路徑庫模塊
  • 內置的 open 函數和 io.open
  • shutil.disk_usage

只需包含fs fixture 即可修補這些模塊。 如果你真的需要使用pyfakefs ,要么提供你的代碼所期望的一切(甚至是間接的),要么用暫停的fs開始你的測試,並只啟用它來測試無法通過其他方式測試的特定內容。 在這種情況下,是io.open中斷了。


在執行依賴於文件存在的函數之前,通過調用fs.add_real_directory來提供預期的文件,如下所示:

def test_package_path(fs):
    fs.add_real_directory(os.path.dirname(importlib.__file__))
    print_package_path()

,其中importlib.__file__需要替換為測試代碼中importlib.resources.path訪問的任何內容的完整路徑。 此方法對於在測試函數中創建文件也是安全的,因為假 fs 知道所有更改並且從不將它們應用於實際文件:

默認情況下,對文件的訪問是只讀的,但即使您使用 read_only=False 添加它們,文件也只會寫入假系統(例如內存)。 真正的文件永遠不會改變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM