Python versions not finding Glyphs python version / GlyphsApp / objc

Hey,

when trying to get some scripts to run I am seeing odd issues with Python environments and I am not really sure what is the current “supposed to be” state for G 3.

In the Preferences, I have these — from another thread I gathered there should be a “Glyphs” python version there as well?

When checking the Macro python version and installed modules for that Python I get:

Particularly, there seems to be no “GlyphsApp” module available. As you can see in the above (two up) Macro window screenshot, the path seems to include the G 3 folders though.

Hard to understand what should be used and why it’s failing. Also, my Python environments I use are installed via pyenv. Is there supposed to be Glyph’s own Python version in the preferences? And if so, how do you install packages there? Or if any can be picked, how and where from do you get it to use the GlyphsApp module (which supposedly needs the objc to be already loaded, first)?

confused
-J

Install the Glyphs Python from WindowPlugin ManagerModulesPython. After installing, relaunch Glyphs for the option to appear in preferences. Select it and relaunch Glyphs again to load the new Python. Other Python version might also work, but with the Glyphs version you are on the save side of plugin compatibility.

1 Like

Ah, I see. Thanks.

What’s the point of being able to pick the python versions, if you need to install the Glyphs-python and can only use that one (I mean, … you likely want access to the GlyphsApp module, so any other python versions will always miss that one, no?)?

So with Glyph’s python active, how do I pip install for Glyphs to find those modules? Without hijacking stuff into one of those path folders?

And “wild guesses” like this have failed to install anything:

Johanness-MacBook-Pro-4:Glyph-Filters johannes$ /Users/johannes/Library/Application\ Support/Glyphs\ 3/Repositories/GlyphsPythonPlugin/Python.framework/Versions/3.9/bin/pip install noise

-bash: /Users/johannes/Library/Application Support/Glyphs 3/Repositories/GlyphsPythonPlugin/Python.framework/Versions/3.9/bin/pip: /Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9: bad interpreter: No such file or directory

Johanness-MacBook-Pro-4:Glyph-Filters johannes$ /Users/johannes/Library/Application\ Support/Glyphs\ 3/Repositories/GlyphsPythonPlugin/Python.framework/Versions/3.9/bin/python3 -m install noise

dyld: Library not loaded: /Library/Frameworks/Python.framework/Versions/3.9/Python
  Referenced from: /Users/johannes/Library/Application Support/Glyphs 3/Repositories/GlyphsPythonPlugin/Python.framework/Versions/3.9/bin/python3
  Reason: image not found
Abort trap: 6

You can use your manually installed versions just fine. You just need to install PyobjC:

pip3 install pyobjc
1 Like

Hm, not sure then what is causing this. Seems to be same python environment (?), but in the macro window objc seems missing. Maybe something to do with the PATH order?

I’m quite sure that Glyphs can’t load a python version inside a .pyenv. So you need to install pyobjc in brew version directly.

Aha.

Okay, so for any other pyenv users:

Find your brew installed python version:

Johanness-MacBook-Pro-4:axi johannes$ brew info python@3.9
python@3.9: stable 3.9.7 (bottled)
Interpreted, interactive, object-oriented programming language
https://www.python.org/
/usr/local/Cellar/python@3.9/3.9.1_6 (3,933 files, 65.4MB)
  Poured from bottle on 2021-02-01 at 14:15:53
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/python@3.9.rb
License: Python-2.0
==> Dependencies
Build: pkg-config ✔...

Then to install directly into the brew python version’s packages which Glyphs will use:

/usr/local/Cellar/python@3.9/3.9.1_6/bin/python3.9 -m pip install whatever

Obviously change your versions as needed.

Also, @GeorgSeifert , this defeats the entire point of having separate pyenv versions if you have to install whatever some script needs into your global python which all pyenv’s inherit from when created, no? I mean, I cannot have several brew python@3.9’s, but only the one I’m messing up now…


As of June 2024 brew info will give you a shortcut to the version specific binaries:

brew info python@3.11
==> python@3.11: stable 3.11.9 (bottled)
Interpreted, interactive, object-oriented programming language
https://www.python.org/
/opt/homebrew/Cellar/python@3.11/3.11.9 (3,359 files, 63.3MB) *
  Poured from bottle using the formulae.brew.sh API on 2024-04-04 at 13:19:04
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/p/python@3.11.rb
License: Python-2.0
==> Dependencies
Build: pkg-config ✔
Required: mpdecimal ✔, openssl@3 ✔, sqlite ✔, xz ✔
==> Caveats
Python has been installed as
  /opt/homebrew/bin/python3.11

Unversioned and major-versioned symlinks `python`, `python3`, `python-config`, `python3-config`, `pip`, `pip3`, etc. pointing to
`python3.11`, `python3.11-config`, `pip3.11` etc., respectively, have been installed into
  /opt/homebrew/opt/python@3.11/libexec/bin

You can install Python packages with
  pip3.11 install <package>
They will install into the site-package directory
  /opt/homebrew/lib/python3.11/site-packages
...

e.g. that last bit: pip3.11 install <package>

There are too many different setups for environments. Glyphs can’t know where to find them.

If your environment contains a Python.framework, you could tell Glyphs about it like this:

Glyphs.defaults["GSPythonFrameworkPath"] = "path/to/folder/containing/framework"

@GeorgSeifert when using Glyph’s packaged python, what would be the correct way to pip install into that specific python environment?

See the Extending Glyphs tutorial for an explanation and additional installations you can do.

I am asking specifically because even with my homebrew version I seem to get some packages from the packaged python, and it confuses me. I don’t need to use a homebrew version for Glyphs if I can pip install into the Glyphs python environment, which is what I asked.

If the only method to pip install custom packages is to not use the packaged python that is okay, too.

Using pip for the “(Glyphs)” Python installation is fairly recent. You can see an example use here:

This will get easier as we figure out how to best offer pip to extension developers. If you have any questions, let us know!

1 Like

Ah, this is interesting, so this would run a pip install from inside a plugin?

What I was interest in is installing packages into the python environment that Glyphs uses (when using Glyph’s packaged environment in the Settings), something like /where/is/glyphs/python/bin/pip install ... … where is it and can I install like this from terminal?

The path depends on the version of Python. Currently, it’s

/Users/USERNAME/Library/Application Support/Glyphs 3/Repositories/GlyphsPythonPlugin/Python.framework/Versions/3.11

which you can get dynamically in Python as

from GlyphsApp import GSScriptingHandler
GSScriptingHandler.sharedHandler().currentPythonPath()

With that, you can use PIP like so:

.../3.11/bin/python3 -m pip install --target TARGET ...

where TARGET is

/Users/USERNAME/Library/Application Support/Glyphs 3/Scripts/site-packages

which you can get dynamically in Python as

GSGlyphsInfo.applicationSupportPath() + '/Scripts/site-packages'
1 Like

Is that so? Is this a good/secure thing to allow plugin developers to randomly install anything via pip?

Asking as a developer myself.

It’s no more good/secure than other existing avenues, just easier. If you need to “pip install” something just for your plugin, install those dependencies outside of the shared site-packages directory so you don’t introduce conflicts.

It’s all still more mechanical than it should be. Ideally, you could define requirements in the package index or somewhere else and Glyphs would manage those requirements for you. But how exactly that should happen is still an open question.

1 Like

The requirement thingy is already working (at least partially). I use it for the paddle framework like that.

There are some modules that can only be installed by pip and not by cloning a repo.
In Python projects, this is done by specifying needed modules in “requirements.txt”. We are thinking to do something similar. I thought about adding a “requirements” key to the packages file, but maybe we can actually support “requirements.txt”

The requirements.txt is usually used to recreate an exact environment with exact version numbers of all participating packages. That may lead to conflicts between package versions when they are installed into Glyphs’ site-packages.

A better solution would be to use the install_requires key from “modern” Python packages’ setup.cfg file, as it can be used to specify minimum and maximum package versions:

install_requires =
    defcon >= 0.10.3
    fontmake >= 3.9.0
    glyphspkg >= 0.1.10
    lfFontTools[dsig,fontbakery,pdf,ttinst,ufo] >= 0.43.21, < 0.44.0
    htmlgenerator >= 1.4.16
    pyyaml >= 6.0.1
    ufonormalizer >= 0.6.1
    vfblib >= 0.6.5
    # We want specific versions of harfbuzz to get reproducible builds
    uharfbuzz == 0.39.1
    vharfbuzz == 0.3.0

That might increase the chances that a matching package version can be found for all installed plugins.