Many scripts and plug-ins continue to run in Glyphs 4 just as they did in Glyphs 3. However, some code needs to be updated to work in Glyphs 4 as well.
Python version
Glyphs 4 supports Python 3.14 and later.
Checking the app version
Use Glyphs.versionNumber to conditionally run code depending on the Glyphs app version:
from GlyphsApp import Glyphs
if Glyphs.versionNumber >= 4.0:
# ...
else:
# ...
Avoid wildcard imports
In general, avoid importing using the wildcard * keyword. Instead, use explicit imports:
# avoid wildcards like this one:
from GlyphsApp import *
# prefer explicit imports:
from GlyphsApp import Glyphs, GSFont, GSGlyph, GSLayer
# ...
Such explicit imports work in Glyphs 3 as well.
Redrawing Edit View
If you want to manually redraw an Edit View tab, do so using the redraw() API:
if Glyphs.versionNumber >= 4.0:
tab.redraw()
else:
tab.forceRedraw()
API changes
GSInstance.fileName(format) now requires an explicit format constant as a parameter.
Intermediate (brace) and Alternate (bracket) layers API that was exposed as methods in Glyphs 3 is now exposed as properties:
# Glyphs 3:
someLayer.isBraceLayer() || someLayer.isBracketLayer()
# Glyphs 4:
someLayer.isBraceLayer || someLayer.isBracketLayer
Smart Glyphs
Smart Glyphs now use axes, just like the variation axes of a font. Access them as someGlyph.axes.
| Glyphs 3 | Glyphs 4 |
|---|---|
glyph.smartComponentAxes with GSPartProperty |
glyph.axes with GSAxis |
layer.smartComponentPoleMapping[property.name] |
layer.coordinates()[axis.axisId] |
component.smartComponentValues[property.id] |
component.smartComponentValues[axis.axisId] |
Use someLayer.axesValues to get the axis coordinates of the layer (font axis coordinates first, for layers of Smart Glyphs the coordinates of the glyph axis second).
Constants
The old direction constants BIDI, LTR, RTL, RTLTTB, and LTRTTB are not exported by Glyphs 4. Use GSBIDI, GSLTR, GSRTL, GSVertical, and GSVerticalToRight.
GSAlignmentDisable is GSAlignmentDisabled in Glyphs 4.
VARIABLE changed its value, ensure you are using the constant and not its old value "variable" directly.
Using code checkers
Glyphs 4 provides .pyi files that provide type hints for type checking tools like Pylance or pyright.
If you use Visual Studio Code, you can add the following to your .vscode/settings.json file:
"flake8.args": [
"--ignore=W191,E266,E501,E265,E722,W503,E303,E262,E701,E741,E261",
"--verbose"
],
"python.analysis.extraPaths": [
"/Applications/Glyphs 4.app/Contents/Scripts/typing/",
"/Applications/Glyphs 4.app/Contents/Scripts/GlyphsApp/",
"/Applications/Glyphs 4.app/Contents/Scripts/",
"~/Library/Application Support/Glyphs 4/Scripts/"
]
(adjust the --ignore entries to your liking.)
Or, if you use pyright and ruff (e.g. in the Scripting Window), put this into pyrightconfig.json
{
"extraPaths": [
"/Applications/Glyphs 4.app/Contents/Scripts/typing/",
"/Applications/Glyphs 4.app/Contents/Scripts/GlyphsApp/",
"/Applications/Glyphs 4.app/Contents/Scripts/",
"~/Library/Application Support/Glyphs 4/Scripts/"
],
"typeCheckingMode": "basic",
"reportDeprecated": "warning"
}
and ruff.toml:
[lint]
preview = true
select = [
"E", # pycodestyle errors (stable rules)
"W", # pycodestyle warnings (stable rules)
"F", # pyflakes (unused imports/variables, undefined names, …)
# preview-gated pycodestyle rules flake8 would check:
"E111", # indentation is not a multiple of the indent size
"E112", # expected an indented block
"E113", # unexpectedly indented
"E114", # indentation is not a multiple of the indent size (comment)
"E115", # expected an indented block (comment)
"E116", # unexpected indentation (comment)
"E117", # over-indented
"E124", # closing bracket does not match visual indentation
"E128", # continuation line under-indented for visual indent
"E201", # whitespace after '('
"E202", # whitespace before ')'
"E203", # whitespace before ':' ',' ';'
"E211", # whitespace before '(' or '['
"E221", # multiple spaces before operator
"E222", # multiple spaces after operator
"E223", # tab before operator
"E224", # tab after operator
"E225", # missing whitespace around operator
"E226", # missing whitespace around arithmetic operator
"E227", # missing whitespace around bitwise or shift operator
"E228", # missing whitespace around modulo operator
"E231", # missing whitespace after ',' ';' or ':'
"E241", # multiple spaces after comma
"E242", # tab after comma
"E251", # unexpected spaces around keyword / parameter equals
"E252", # missing whitespace around parameter equals
"E301", # expected 1 blank line between methods
"E302", # expected 2 blank lines before top-level definition
"E303", # too many blank lines (ignored below, kept for completeness)
"E304", # blank lines after function decorator
"E305", # expected 2 blank lines after class or function definition
"E306", # expected 1 blank line before nested definition
"E502", # redundant backslash between brackets
"W391", # blank line at end of file
]
ignore = [
"W191", # tab indentation
"E266", # too many leading # for block comment
"E501", # line too long
"E265", # block comment should start with '# '
"E722", # bare except
"E303", # too many blank lines
"E262", # inline comment should start with '# '
"E701", # multiple statements on one line (colon)
"E741", # ambiguous variable name
"E261", # two spaces before inline comment
]