From 955ba58457acfd2bb740f8909ff65060eba831e9 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Wed, 31 Jul 2024 16:33:52 +0100 Subject: [PATCH 1/2] classes_test: test repr(GSLayer) doesn't crash for orphan glyphs reproduces https://github.com/googlefonts/glyphsLib/issues/1014 --- tests/classes_test.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/classes_test.py b/tests/classes_test.py index 5f335cc9e..f4819c561 100755 --- a/tests/classes_test.py +++ b/tests/classes_test.py @@ -1091,6 +1091,27 @@ def test_repr(self): layer = self.layer self.assertIsNotNone(layer.__repr__()) + def test_repr_orphan_glyph(self): + # https://github.com/googlefonts/glyphsLib/issues/1014 + layer = GSLayer() + self.assertIsNone(layer.parent) # orphan layer + + expected = '' + self.assertEqual(repr(layer), expected) + + layer.layerId = layer.associatedMasterId = "layer-0" + self.assertTrue(layer._is_master_layer) + self.assertEqual(repr(layer), expected) + + parent = GSGlyph() + parent.layers.append(layer) + self.assertEqual(layer.parent, parent) # no longer orphan layer + self.assertIsNone(parent.parent) # but still orphan glyph + + # this should not crash with + # AttributeError: 'NoneType' object has no attribute 'masterForId' + self.assertEqual(repr(layer), expected) + def test_parent(self): self.assertIs(self.layer.parent, self.glyph) self.assertIs(self.layer._background.parent, self.glyph) From 98bcee80b154ebe3933cc3c6b4e34b3ec84a2f89 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Wed, 31 Jul 2024 16:34:27 +0100 Subject: [PATCH 2/2] GSLayer: fix name property when parent GSGlyph is in turn orphan Fixes #1014 --- Lib/glyphsLib/classes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/glyphsLib/classes.py b/Lib/glyphsLib/classes.py index 0e9e5c33c..bb40b5ee2 100755 --- a/Lib/glyphsLib/classes.py +++ b/Lib/glyphsLib/classes.py @@ -3742,7 +3742,12 @@ def _is_master_layer(self): @property def name(self): - if self.associatedMasterId and self._is_master_layer and self.parent: + if ( + self.associatedMasterId + and self._is_master_layer + and self.parent + and self.parent.parent + ): master = self.parent.parent.masterForId(self.associatedMasterId) if master: return master.name