[英]How to use importlib.resources.path(package, resource)?
[英]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.