Given some installed package, the following code can be used to print its location on the filesystem:
import importlib.resources
def print_package_path(pkg):
with importlib.resources.path(pkg, "") as path:
print(path)
print_package_path("importlib")
# /home/me/python_3.8/lib/python3.8/importlib on my machine
If I want to test a function that contains such a statement with pytest
as the test suite and pyfakefs
to fake the filesystem during the test, it will crash with a confusing error (IsADirectoryError: [Errno 21] Is a directory
on ubuntu and PermissionError: [Errno 13] Permission denied
on windows) - it's not even necessary to do anything with the fs
fixture, it just needs to be part of the test function's signature, e.g.
def test_package_path(fs):
print_package_path("importlib")
will result in
______________________________ 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
which makes zero sense to me. Should a directory never have been usable as a resource in the first place?
I must admit I don't really understand the importlib.resources
module, so I might just be using it wrong (my actual use case is creating a file during development, and avoiding the use of __file__
to find the right location).