-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PermissionError when attempting to use importlib.resources on Windows to load a custom font with ImageFont #6324
Comments
Hi. If you'll permit me to ask a quick question, just to rule out the easy solution, does the problem persist if you don't use Pillow? import importlib.resources
if __name__ == "__main__":
with importlib.resources.path("font_demo", "OpenSans-Regular.ttf") as path:
pass |
No, that works fine. However, this does cause an error: with importlib.resources.path("font_demo", "OpenSans-Regular.ttf") as path:
font = ImageFont.truetype(str(path), 30) So it seems my minimal example is not so minimal - you don't even need to use the font. |
When using a truetype font, the font file itself is opened using the FreeType library. Looking at the code, it should be properly closed when the font object is deallocated, so adding a If you need to remove the file before the font is deallocated, you should be able to load the font using a file-like object, perhaps like this: with importlib.resources.path("font_demo", "OpenSans-Regular.ttf") as path:
with open(path, "rb") as f:
font = ImageFont.truetype(f, 30) |
Thanks @nulano. This is not the first problem we've had with FreeType keeping the font open - #3730 (comment) |
Yeah, managing the file opening/closing myself seems like the best option. Thanks. By the way, it's probably obvious to any PIL contributor, but this is the absolute simplest example I can get to reproduce the bug: import importlib.resources
from PIL import ImageFont
from PIL import _imagingft as core
if __name__ == "__main__":
with importlib.resources.path("font_demo", "OpenSans-Regular.ttf") as path:
font = core.getfont(
str(path),
30,
0,
"",
layout_engine=ImageFont.Layout.BASIC
)
After that, it seems like you're in native code. |
@geajack are you happy for this issue to be closed? |
If it's an upstream issue that you don't intend to try and workaround in Pillow then that seems fine. |
The issue is that your code keeps a reference to the font (keeping the file open via FreeType) while trying to delete the file. It is unclear whether FreeType keeping the file open while in use is an (upstream) issue or not. It seems reasonable to me to keep the file open while the font may still be used. From the comment linked by @radarhere:
|
I see. Maybe this is just a documentation issue? It's pretty non-obvious behavior after all - how often do you usually have to think about exactly when the garbage collector runs while programming in Python? Perhaps a note in the docs that the file will remain locked as long as the font object exists, and so if you need to do anything else with the file while the Python process is still running you should use the file-like object overload. |
I've created PR #6485 to add a note to the documentation, resolving this. |
Behavior
My code calls
ImageFont.truetype
to load a font. Because I want to make sure that font is present on the system, I commited it to my repo. When I want to make my package pip installable, I decided to package my font file usingimportlib.resources
. But now, when I pip install the package on Windows and try and run the code, I get aPermissionError
whenimportlib
attempts to clean up the temporary file - probably because Windows thinks a process is still using it:I don't get this with other kinds of resource files, so it seems Pillow is not releasing the file correctly. I have not tested this on other operating systems, but I suspect this is a Windows-only bug.
Reproduction
pip install pillow
).python -m font_demo
. You should see an image that says "Hello, world!".python -m setup.py install
to install the package.python -m font_demo
again.PermissionError
and the program halts without displaying the image.What are your OS, Python and Pillow versions?
The text was updated successfully, but these errors were encountered: