从 f 字符串中提取表达式

Extracting expressions from an f-string

我正在编写一个 python 工具,它既可以执行静态 python 代码分析,又可以对该代码执行一些自动重写(例如扩展通配符导入)。我需要此工具做的部分工作是提取出出现在 f 字符串中的所有表达式,理想情况下其格式与它们在代码中出现的方式完全相同。

f'{a+b} {c   *d}'  -> ['a+b', 'c   *d']
f'{int("3" * 2):d}'  -> ['int("3" * 2)']

我能想到的最好的解决方案是 returns 表达式,但不保留原始格式:

import ast  # requires python3.9 for ast.unparse()
def extract(s):
    values = ast.parse(f"f'{s}'").body[0].value.values
    fvalues = [v for v in values if isinstance(v, ast.FormattedValue)]
    return [ast.unparse(t.value) for t in fvalues]

>>> extract('{a+b} {c   *d}')
['a + b', 'c * d']
>>> extract('{int("3" * 2):d}')
["int('3' * 2)"]

就我的工具而言,我可以从中获得一些价值,但我真的更愿意保留原始格式。除了复制 python 解释器实现中存在的 intricate f-string parsing logic 之外,是否有一个干净的解决方案? (我到底在哪里可以找到那个逻辑?Python-ast.h 似乎没有。)

redbaron 模块通常承诺将 python 代码解析为保留格式的抽象语法树,但它似乎不支持 f-strings。

documentation for the ast module 底部有一个“另请参阅”框,其中包含一些应该对您有所帮助的选项,包括:

(其他一些可能也有帮助,但我不能简单地看一下。)