Changing userData does not always mark the document modified

Calling:

Glyphs.font.masters[0].userData["foo"] = {}

will mark the document modified (i.e. the user is prompted to save before closing), but after that neither of the following will mark it modified:

Glyphs.font.masters[0].userData["foo"]["bar"] = {}
Glyphs.font.masters[0].userData["foo"] = {}

I had to delete it first:

data = Glyphs.font.masters[0].userData["foo"]
data["bar"] = {}
del Glyphs.font.masters[0].userData["foo"]
Glyphs.font.masters[0].userData["foo"] = data

Is this intentional? Is there a way to manually mark the document modified?

Only changed to the root object will be noticed. when setting the data, it checks for equality with the existing value. In your example, you are setting bar in the actual object and when you assign data userData["foo"], it is already in there (and the equal check will be true).

So this should work:

data = Glyphs.font.masters[0].userData["foo"].mutableCopy() # not the objc copy method. Any python copy method should work, too
data["bar"] = {"test": 2}
Glyphs.font.masters[0].userData["foo"] = data

This works, but if I later do the same but calling data["bar"]["test2"] = 3, the document will not be marked modified. Looks like I have to do the copy for each sub dictionary.

Or do the copying in the setter line, too.

data = Glyphs.font.masters[0].userData["foo"].mutableCopy() # not the objc copy method. Any python copy method should work, too
data["bar"] = {"test": 2}
Glyphs.font.masters[0].userData["foo"] = data.mutableCopy()

Is there any other place where setting something in a dict would notify the container about changes and undo?

I don’t really know, I was a bit surprised but I also don’t know what to expect, so I’m happy I have a solution now.