If you define a sum type like
expr = Unary(expr e) | Binary(expr left, expr right)
Then you will get three pieces of generated code:
expr_e.Unary: An integer tag.
if node.tag == expr_e.Unaryexpr.Unary(): A Python class / type / constructor.
node = expr.Unary(child)expr__Unary(). MyPy seems to like this form better. It makes it easier to statically type the code.expr_t: A common superclass of all the nodes.
isinstance(node, expr_t)The implementation is here, with some more notes in the README.
https://github.com/oilshell/oil/tree/master/asdl
For conceptual background, see blog posts tagged #ASDL or the original Zephyr technical report.