fontParts icon indicating copy to clipboard operation
fontParts copied to clipboard

OpenFont() misleading feedback

Open roberto-arista opened this issue 4 years ago • 4 comments

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

roberto-arista avatar Feb 01 '22 10:02 roberto-arista

You could add an isinstance(path, (str, os.PathLike)) check in OpenFont somewhere, and raise TypeError if False.

justvanrossum avatar Feb 01 '22 10:02 justvanrossum

wouldn't this check shadow this option https://github.com/robotools/fontParts/blob/master/Lib/fontParts/fontshell/font.py#L39 ?

roberto-arista avatar Feb 01 '22 10:02 roberto-arista

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.

justvanrossum avatar Feb 01 '22 12:02 justvanrossum

  • 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__

typemytype avatar Feb 01 '22 13:02 typemytype