Wenn ich Quellcode mit dem ast
Modul analysieren, warum ist das lineno
Attribut eines Name
innerhalb eines FormattedValue
auf 1 gesetzt, auch wenn die f-String ist nicht auf Linie 1?Zeilennummern von Python f-Strings in abstrakte Syntaxbaum
Ich versuche zu sehen, welche Zeilen des Quellcodes in einer Funktionsdefinition enthalten sind, also gehe ich die abstrakten Syntaxbaumknoten unter dem FunctionDef
Knoten. Ich sammle alle lineno
Attribute in eine Menge, und das sagt mir, welche Linien sind Teil der Funktionsdefinition.
Wenn jedoch f-strings in Python 3.6 erschien, haben sie diese Technik irgendwie durchbrochen. Hier ist ein Beispiel für das Problem:
import ast
code = """\
f'x{y}'
"""
tree = ast.parse(code)
print(ast.dump(tree, include_attributes=True))
Hier ist die Ausgabe von diesem Skript:
Module(body=[Expr(value=JoinedStr(values=[Str(s='x', lineno=2, col_offset=0), FormattedValue(value=Name(id='y', ctx=Load(), lineno=1, col_offset=1), conversion=-1, format_spec=None, lineno=2, col_offset=0)], lineno=2, col_offset=0), lineno=2, col_offset=0)])
Ich weiß, das ist ziemlich unleserlich, so ist hier die gleiche Leistung mit einigen zusätzlichen Leerzeichen:
Module(body=[Expr(value=JoinedStr(values=[
Str(s='x', lineno=2, col_offset=0),
FormattedValue(value=Name(id='y',
ctx=Load(),
lineno=1,
col_offset=1),
conversion=-1,
format_spec=None,
lineno=2,
col_offset=0)], lineno=2, col_offset=0), lineno=2, col_offset=0)])
Der einzige Quellcode war in Zeile 2, also was ist mit diesem Teil der Ausgabe?
Name(id='y',
ctx=Load(),
lineno=1,
col_offset=1)
Ich dachte, es könnte die Zeilennummer innerhalb die Zeichenfolge sein, aber wenn ich dies versuchen, meldet es noch lineno=1
.
code = """\
f'''
x{y}'''
"""