OpenFont() misleading feedback
Hi all!
Yesterday I was trying to open a specific ufo sitting in a folder full of ufos using fontParts.shell, using some code like this:
from pathlib import Path
import fontParts.world as fp
folderPath = Path().cwd() / "ufos"
regularStylePath = [pp for pp in folderPath.iterdir() if pp.suffix == ".ufo" and "Regular" in pp.name]
regularStyle = fp.OpenFont(regularStylePath)
print(regularStyle)
and I received the following traceback
Traceback (most recent call last):
File "/Users/robertoarista/Documents/Repositories/someFolder/anotherFolder/loadSpecificUfo.py", line 9, in <module>
print(regularStyle)
File "/Users/robertoarista/Library/Caches/pypoetry/virtualenvs/virtualEnvName/lib/python3.10/site-packages/fontParts/base/base.py", line 134, in __repr__
contents = self._reprContents()
File "/Users/robertoarista/Library/Caches/pypoetry/virtualenvs/virtualEnvName/lib/python3.10/site-packages/fontParts/base/font.py", line 41, in _reprContents
"'%s %s'" % (self.info.familyName, self.info.styleName),
File "/Users/robertoarista/Library/Caches/pypoetry/virtualenvs/virtualEnvName/lib/python3.10/site-packages/fontParts/base/base.py", line 90, in __get__
return getter()
File "/Users/robertoarista/Library/Caches/pypoetry/virtualenvs/virtualEnvName/lib/python3.10/site-packages/fontParts/base/font.py", line 421, in _get_base_info
info = self._get_info()
File "/Users/robertoarista/Library/Caches/pypoetry/virtualenvs/virtualEnvName/lib/python3.10/site-packages/fontParts/fontshell/font.py", line 65, in _get_info
return self.infoClass(wrap=self.naked().info)
AttributeError: 'list' object has no attribute 'info'
This is due to the fact that I forgot to unwrap the regular style path from the list, so the correct code would be
from pathlib import Path
import fontParts.world as fp
folderPath = Path().cwd() / "ufos"
regularStylePath = [pp for pp in folderPath.iterdir() if pp.suffix == ".ufo" and "Regular" in pp.name][0]
regularStyle = fp.OpenFont(regularStylePath)
print(regularStyle)
I also understand that this behaviour is intended, as a Font-like object might be used from the API. The interpreter is complaining about the fact that a list does not have an info attribute. Nevertheless, I would imagine this kind of traceback to be a bit misleading for beginners (it took a while to me to understand that I was not dealing with a corrupt ufo). Could the error message be improved somehow?
cc @typemytype
You could add an isinstance(path, (str, os.PathLike)) check in OpenFont somewhere, and raise TypeError if False.
wouldn't this check shadow this option https://github.com/robotools/fontParts/blob/master/Lib/fontParts/fontshell/font.py#L39 ?
Ah yes, you're right. Then: what kind of font objects are accepted there? Probably cls.wrapClass? Hmmm, that may be too strict, as it seems it may accept font-like objects (perhaps ufoLib2.Font?).
Dumb idea: perhaps check for hasattr(pathOrObject, "info"), as that is the error you're encountering... Not perfect, but would have made the error clearer in your case.
-
trust
isisntance(pathOrObject, cls.wrapClass) -
and maybe validate the incoming object on a minimum required api... same has to happen downstream for glyph-like objects (this would probably be overkill)
font.info
font.lib
font.kerning
font.groups
font.features
font.__getitem__