My journey creating a dataclass converter by using abstract syntax trees, match-case, the dedent utility and more. You may learn something new along the way.
Table of contents
How does this undataclass.py
script work?
Essentially the undaclass.py
script:
- Parses the contents of a Python file into an abstract syntax tree (using the
ast
module) - Identifies dataclass-related AST nodes representing dataclasses, dataclass fields, and
__post_init__
methods - Builds up strings representing Python code for the various equivalent non-dataclass methods
- Parses those strings into AST nodes and injects them into the was-a-dataclass node
- Converts all the AST nodes back into Python code
I used some tricks I don't usually get to use in Python. I used:
- Many very hairy
match
-case
blocks which replaced even hairierif
-elif
blocks - A sentinel object to keep track of a location that needed replacing
- Python's
textwrap.dedent
utility, which I feel should be more widely known & used - slice assignment to inject one list into another
- The
ast
module'sunparse
function to convert an abstract syntax tree into Python code
Let's take a look at some of the code.
Structural pattern matching
Python's structural pattern matching can …