Comment gérer une erreur tokenize avec des commentaires multilignes non terminés (python 2.6)
-
08-07-2019 - |
Question
L'exemple de code suivant:
import token, tokenize, StringIO
def generate_tokens(src):
rawstr = StringIO.StringIO(unicode(src))
tokens = tokenize.generate_tokens(rawstr.readline)
for i, item in enumerate(tokens):
toktype, toktext, (srow,scol), (erow,ecol), line = item
print i, token.tok_name[toktype], toktext
s = \
"""
def test(x):
\"\"\" test with an unterminated docstring
"""
generate_tokens(s)
provoque le déclenchement des actions suivantes:
... (stripped a little)
File "/usr/lib/python2.6/tokenize.py", line 296, in generate_tokens
raise TokenError, ("EOF in multi-line string", strstart)
tokenize.TokenError: ('EOF in multi-line string', (3, 5))
Quelques questions sur ce comportement:
- Dois-je attraper et ignorer «sélectivement» tokenize.TokenError ici? Ou dois-je arrêter d'essayer de générer des jetons à partir de code non conforme / non complet? Si oui, comment pourrais-je vérifier cela?
- Cette erreur (ou des erreurs similaires) peut-elle être causée par autre chose que docstring non terminé?
La solution
La façon dont vous gérez les erreurs de tokenize dépend entièrement de la raison pour laquelle vous effectuez un tokenizing. Votre code vous donne tous les jetons valides jusqu'au début du littéral de chaîne incorrecte. Si ce flux de jetons vous est utile, utilisez-le.
Vous avez quelques options pour savoir quoi faire avec l'erreur:
-
Vous pouvez l'ignorer et créer un flux de jetons incomplet.
-
Vous pouvez mettre tous les jetons en mémoire tampon et utiliser le flux de jetons si aucune erreur ne survient.
-
Vous pouvez traiter les jetons, mais interrompre le traitement de niveau supérieur en cas d'erreur.
Pour savoir si cette erreur peut se produire avec autre chose qu'une docstring incomplète, oui. Rappelez-vous que les docstrings ne sont que des littéraux de chaîne. Tout littéral de chaîne multiligne non terminé vous donnera la même erreur. Des erreurs similaires pourraient se produire pour d'autres erreurs lexicales dans le code.
Par exemple, voici d'autres valeurs de s qui génèrent des erreurs (au moins avec Python 2.5):
s = ")" # EOF in multi-line statement
s = "(" # EOF in multi-line statement
s = "]" # EOF in multi-line statement
s = "[" # EOF in multi-line statement
s = "}" # EOF in multi-line statement
s = "{" # EOF in multi-line statement
Curieusement, d’autres entrées non sensuelles produisent des valeurs ERRORTOKEN à la place:
s = "<*>quot;
s = "'"