Как разобрать код Python, сохраняя строковые литералы в точности как есть? - PullRequest
3 голосов
/ 28 мая 2019

Я пытаюсь просмотреть все строковые литералы в исходном коде Python, но не могу сказать, какой тип строкового литерала у каждого.

К сожалению, как вы можете видеть в этом примере, ast.parse не работает:

[node.value.s for node in ast.parse('\'x\'; u\'x\'; b\'x\'; "x"; u"x"; b"x"').body]

Вывод:

['x', 'x', b'x', 'x', 'x', b'x']

означает, что я не могу различить литералы '' и u'' или '' и "" и т. Д.

Как я могу разобрать исходный код Python при сохранении исходного литерала в точности как написано?

Есть ли встроенный способ?

1 Ответ

3 голосов
/ 28 мая 2019

Информация, которую вы ищете, не является информацией уровня AST.Подходящим уровнем для проверки подобных вещей является уровень токена, и вы можете использовать для этого модуль tokenize.

API tokenize довольно неудобен - ему нужен вводкоторый ведет себя как метод readline двоичного файла-подобного объекта - поэтому вам нужно открывать файлы в двоичном режиме, и если у вас есть строка, вам нужно будет использовать encode и io.BytesIO для преобразования.

import tokenize
token_stream = tokenize.tokenize(input_file.readline)
for token in token_stream:
    if token.type == tokenize.STRING:
        do_whatever_with(token.string)

Вот версия Python 2 - имена функций разные, и вам необходимо получить доступ к информации о токене позиционно, потому что вместо именованных кортежей вы получаете регулярные кортежи:

import tokenize
token_stream = tokenize.generate_tokens(input_file.readline)
for token_type, token_string, _, _, _ in token_stream:
    if token_type == tokenize.STRING:
        do_whatever_with(token_string)
...