I wrote a library using just ast
and inspect
libraries to parse and emit [uses astor on Python < 3.9] internal Python constructs.
Just realised that I really need to preserve comments afterall. Preferably without resorting to a RedBaron or LibCST; as I just need to emit the unaltered commentary; is there a clean and concise way of comment-preserving parsing/emitting Python source with just stdlib?
What I ended up doing was writing a simple parser, without a meta-language in 339 source lines: https://github.com/offscale/cdd-python/blob/master/cdd/cst_utils.py
if line.lstrip().startswith("#") or line not endswith('\\') and balanced_parens(line)
else continue munching until that condition is true… plus some edge-cases around multiline strings and the like;namedtuple
with a value
property.ast
ast
nodes to modify—not remove—to: {ClassDef
,AsyncFunctionDef
,FunctionDef
} docstring (first body element Constant
|Str
), Assign
and AnnAssign
;cst_idx, cst_node = find_cst_at_ast(cst_list, _node)
;maybe_replace_doc_str_in_function_or_class(_node, cst_idx, cst_list)
cst_list
contains only changes to those aforementioned nodes, and only when that change is more than whitespace, and can be created into a string with "".join(map(attrgetter("value"), cst_list))
for outputting to eval
or straight out to a source file (e.g., in-place overriding).match
/case
is supported, but if there's new syntax introduced since, it isn't [yet?] supported… at least not automatically);