Analysieren von wörtlichen Zuweisungen aus einer Python-Datei

Gesucht: Eine Python 3-Bibliothek (die hoffentlich auch Python 2 unterstützt), die eine Python-Datei mit Zuweisungen von Literalwerten (insbesondere alles, was durch analysiert werden kann ast.literal_eval) zu Variablen nimmt und a dictdes resultierenden Namensraums zurückgibt. Wenn die Datei nicht wörtliche Zuweisungen enthält, löst die Bibliothek entweder einen Fehler aus oder ignoriert sie.

Beispielsweise sollte die Bibliothek in der Lage sein, eine Datei wie folgt umzuwandeln:

foo = 42
bar = [{"quux": None, "glarch": True}]
foo = 'reassigned'

in den Wert:

{
    "bar": [{"quux": None, "glarch": True}],
    "foo": "reassigned"
}

und eine Datei wie diese:

foo = range(42)
bar = 2 + 2
quux = input()
glarch = 'Hi!'

würde entweder einen Fehler erzeugen oder als einfach enden, {"glarch": "Hi!"}ohne tatsächlich das range()oder input()auszuführen (Bonuspunkte, wenn es das parsen kann bar = 2 + 2, obwohl).

(Ich hätte schwören können, dass ich eine solche Bibliothek schon einmal gesehen habe, möglicherweise als Teil von Django, aber ich kann sie nicht mehr finden.)

Antworten (1)

Ich kenne keine Bibliothek für diese spezielle Aufgabe, aber mit ast.parse. Hier ist ein Beispiel in Python 3:

import ast

with open("myfile.py", "r") as o:
    src = o.read()
top_level = ast.parse(src)

result = {}
for statement in top_level.body:
    assert isinstance(statement, ast.Assign)
    assert len(statement.targets) == 1
    name = statement.targets[0].id
    result[name] = ast.literal_eval(statement.value)

print(result)

Wenn die Eingabe lautet:

 foo = 42
 bar = [{"quux": None, "glarch": True}]
 foo = 'reassigned'
 bing = 1 + 1

Dann bekommst du:

{'bing': 2, 'foo': 'reassigned', 'bar': [{'glarch': True, 'quux': None}]}
Ich hatte nicht erwartet, dass der Code so einfach ist.