Найти / проверить неукрашенные строковые литералы (без b "или u") в Python - PullRequest
0 голосов
/ 02 июня 2018

В рамках усилий по написанию кода, который последовательно работает как на Python 2, так и на 3, я хотел бы проверить наличие любых неукрашенных строковых литералов (любое открытие "или", которым не предшествует ab или u).

Я в порядке написания тестовых случаев, поэтому мне просто нужна функция, которая возвращает все неукрашенные строковые литералы по моим файлам .py.

В качестве примера, скажем, у меня есть код Python, содержащий следующее:

example_byte_string = b'Это строка из текста ASCII или байтов '

example_unicode_string = u "Это строка Unicode"

example_unadorned_string =' Эта строка не была помечена в любом случае ибудет рассматриваться как байты в Python 2, но Unicode в Python 3 '

example_unadorned_string2 = "Это то, что они называют" строкой "!"

example_unadorned_string3 = "Джон сказал:" Действительно ли это? "очень громко"

Я хочу найти все строки, которые не помечены явно, например, example_unadorned_string, чтобы я мог пометить их правильно и поэтомуили заставить их вести себя одинаково при запуске в Python 2 и 3. Было бы также хорошо разместить кавычки в строках, например example_unadorned_string2 и 3, так как в них не должно быть добавлено u / b к внутренним кавычкам.Очевидно, что в долгосрочной перспективе мы откажемся от поддержки Python 2, и только байты будут нуждаться в явной маркировке.Это соответствует подходу, рекомендованному python-future.org: http://python -future.org / automatic_conversion.html # separating-text-from-bytes

Я могу придумать способысделайте это с grep, которые довольно противны.АСТ выглядит потенциально полезным, тоже.Но я чувствую, что кто-то, должно быть, уже решил эту проблему раньше, поэтому подумал, что я спрошу.

1 Ответ

0 голосов
/ 02 июня 2018

Возможно, вы захотите изучить модуль tokenize ( python2 , python3 ).Грубый пример Python 3 будет выглядеть примерно так:

import tokenize
import token

def iter_unadorned_strings(f):
    tokens = tokenize.tokenize(f.readline)
    for t in tokens:
        if t.type == token.STRING and t.string[0] in ['"', "'"]:
            yield t

fname = r'code_file.py'
if __name__ == '__main__':
    with open(fname, 'rb') as f:
        for s in iter_unadorned_strings(f):
            print(s.start, s.end, s.string)
...