Ich verwende etwas Ähnliches wie das folgende vereinfachte Skript zum Parsen von Python-Schnipseln aus einer größeren Datei:
import io
import tokenize
src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)
src = list(tokenize.tokenize(src.readline))
for tok in src:
print(tok)
src = tokenize.untokenize(src)
Obwohl der Code in python2.x nicht derselbe ist, verwendet er das gleiche Idiom und funktioniert einwandfrei. Wenn ich jedoch das obige Snippet mit Python 3.0 ausführe, erhalte ich diese Ausgabe:
(57, 'utf-8', (0, 0), (0, 0), '')
(1, 'foo', (1, 0), (1, 3), 'foo="bar"')
(53, '=', (1, 3), (1, 4), 'foo="bar"')
(3, '"bar"', (1, 4), (1, 9), 'foo="bar"')
(0, '', (2, 0), (2, 0), '')
Traceback (most recent call last):
File "q.py", line 13, in <module>
src = tokenize.untokenize(src)
File "/usr/local/lib/python3.0/tokenize.py", line 236, in untokenize
out = ut.untokenize(iterable)
File "/usr/local/lib/python3.0/tokenize.py", line 165, in untokenize
self.add_whitespace(start)
File "/usr/local/lib/python3.0/tokenize.py", line 151, in add_whitespace
assert row <= self.prev_row
AssertionError
Ich habe nach Hinweisen auf diesen Fehler und seine Ursachen gesucht, konnte aber keine finden. Was mache ich falsch und wie kann ich ihn beheben?
[Bearbeiten]
Nach partisann Die Beobachtung, dass das Anhängen eines Zeilenumbruchs an den Quelltext den Fehler behebt, hat mich dazu veranlasst, mit der Liste, die ich untoken wollte, herumzuspielen. Es scheint, dass die EOF
Token führt zu einem Fehler, wenn ihm nicht unmittelbar ein Zeilenumbruch vorausgeht, so dass das Entfernen des Tokens den Fehler beseitigt. Das folgende Skript läuft ohne Fehler:
import io
import tokenize
src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)
src = list(tokenize.tokenize(src.readline))
for tok in src:
print(tok)
src = tokenize.untokenize(src[:-1])