Pregunta

Estoy usando algo similar a la siguiente secuencia de comandos simplificada para analizar fragmentos de Python desde un archivo más grande:

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)

A pesar de que el código no es el mismo en python2.X, que utiliza el mismo lenguaje y funciona muy bien. Sin embargo, al ejecutar el código anterior utilizando python3.0, consigo esta salida:

(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

He buscado referencias a este error y sus causas, pero no he podido encontrar ninguna. ¿Qué estoy haciendo mal y cómo puedo corregirlo?

[editar]

partisann 's observación de que añadiendo una nueva línea a la fuente hace que el error desaparezca, empecé a jugar con la lista que fue untokenizing. Parece que el token EOF provoca un error si no inmediatamente precedida por una nueva línea lo que la eliminación se deshace del error. La siguiente secuencia de comandos se ejecuta sin errores:

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])
¿Fue útil?

Solución

src = 'foo="bar"\n'
You olvidó nueva línea.

Otros consejos

Si limita la entrada a untokenize a los 2 primeros elementos de las fichas, parece que funciona.

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 = [t[:2] for t in src]
src = tokenize.untokenize(src)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top