-
-
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
"OSError: cannot open resource" when trying to load more than exactly 509 ImageFonts #3730
Comments
When I run your script with a different font on my macOS machine, I have no problems. However, when I run the following code - from PIL import ImageFont
test = []
for i in range(1000):
print(i)
test.append(open("fonts/AbyssinicaSIL-R.ttf", "r")) It stops at 253 with |
Nope, no problem there. The "too many open files" error occurs only if I try to get beyond 8187 - that's far from the 509 here. :/ |
After a bit of experimenting, the code below seems to work fine as workaround: from PIL import ImageFont
from io import BytesIO
test = []
for i in range(1000):
file = open("fonts/AbyssinicaSIL-R.ttf", "rb")
bytes_font = BytesIO(file.read())
test.append(ImageFont.truetype(bytes_font, 15)) |
Does this happen for just this font, or for multiple different fonts, including standard ones like Helvetica? |
https://docs.microsoft.com/en-us/cpp/c-runtime-library/file-handling?view=vs-2017
I presume that is the limit that you are hitting. So I wouldn't think of this as a bug in Pillow. Any thoughts? |
I randomly choose from a range of different fonts in a directory in my original code, so this happens for other fonts, too. Since the limit is at 512 and this error occurs after exactly 509, I'm not sure if this is connected to each other. Even if it was, a more meaningful exception should be raised in that case. Is there actually any need for the file to be kept open in the current implementation of Pillow when calling ImageFont.truetype? |
I don't know what a more meaningful exception could be. If you have ideas, feel free to put them forward. Pillow is not handling the fonts here by itself, it is making use of FreeType. As an aside to anyone else reading this, now that Pillow has FreeType support in AppVeyor, I was able to replicate the error there. From my understanding, it is FreeType that is actually keeping the file pointer open, and the 'Cannot open resource' message originates from FreeType. We call So I don't see any reasonable action to take to improve this. We could stop using FreeType, but that's extreme. We could load the load into memory, like you're doing with |
If you can track down the "real" error before it's thrown maybe just a reference to that issue could be enough. To stop using FreeType because of this would indeed be decent overkill ;) |
Hi, i experienced the same exact issue where opening exactly 509 fonts will raise an OSError. I'm using Win 10, Python 3.6, Pillow 5.4.1 I'm also working on a project that uses up to 60,000 different fonts. @Luux did you manage to get it resolved? |
@delzac the workaround is to read the font into memory first |
I have the same issue with Windows 10, Python 3.6.8, Pillow 5.4.1. font_path = './some_path/some_font.ttf'
assert os.path.isfile(font_path)
[ImageFont.truetype(font=font_path) for _ in range(1000)] With the workaround of @Luux it is working fine : [ImageFont.truetype(font=BytesIO(open(font_path, "rb").read())) for _ in range(1000)] |
Okay, I'm going to suggest resolving this by noting the situation in the docs - to that end, I've created PR #4020. Let me know if anyone has any thoughts. |
I think documenting it is a great idea! |
Good to document this issue. You could also add the BytesIO workaround in the doc. |
PR #6485 adds a note that copying the files into memory is a workaround. |
What did you do?
For a data generator, I need to use lots of fonts in different sizes. Randomly one of that is used to generate a sample. Since I didn't want to load a font every time we generate a sample, I created a nested dictionary that dynamicalle loads fonts of a given size when it wasn't loaded previously. It worked fine at the beginning. Then I tried to generate some more samples (>1k) and got "OSError: cannot open resource" every time. I double checked the paths and tried to load the font with the same path and that worked just fine. It definitely isn't related to the path encoding bugs.
To reproduce that, you can use the code below.
What did you expect to happen?
It should be able to load fonts until the RAM is full ;)
What actually happened?
OSError after loading exactly 509 fonts.
After clearing my dictionary as soon as the error occurs (temporary workaround), it works fine again.
What are your OS, Python and Pillow versions?
Please include code that reproduces the issue and whenever possible, an image that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.
The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as plone, Django, or buildout, try to replicate the issue just using Pillow.
The text was updated successfully, but these errors were encountered: