It's not quite syntactic sugar, but you're right that (probably) no new object would be created. Based on the "The __match__() Protocol" section [0] of the Pep, matching will call into `Node`'s `__match__` method with `node` as the arg. If Node doesn't have any custom logic here, it'll use the default __match__ implementation [1], which checks `isinstance(node, Node)` like you said, then returns `node` for the python interpreter to check that `node.children` a) is a sequence, b) has two elements, c) has its first element matching `LParen`, using `LParen`'s `__match__` method, and d) has its second element matching `RParen`, using `RParen`'s `__match__` method. If none of these `__match__` methods are overriden, then it does basically function as the parent poster said (though I think it would work even if node.children were some other sequence type (e.g. tuple) containing `LParen()`, `RParen()`).
[0] https://www.python.org/dev/peps/pep-0622/#the-match-protocol [1] https://www.python.org/dev/peps/pep-0622/#default-object-mat...