Как можно безопасно оценить представление литерала, предполагая unicode_literals?

Иногда, когда в процессе dev есть обе рабочие станции WIN и системы LINUX (хостинг), а в коде вы не видите никакого вывода перед соответствующей строкой, это может быть форматирование файла и отсутствие Unix LF (linefeed) заканчивается.

Что мы обычно делаем, чтобы быстро исправить это, переименуйте файл, а в системе LINUX создайте новый файл вместо переименованного, а затем скопируйте его в него. Во многих случаях это решает проблему, так как некоторые из файлов, которые были созданы в WIN, когда-то перемещенные на хостинг, вызывают эту проблему.

Это исправление - это легкое исправление для сайтов, которыми мы управляем по FTP, и иногда может спасти наш новый членов команды некоторое время.

3
задан jez 22 January 2019 в 19:18
поделиться

3 ответа

Что делает коды потенциально небезопасными, так это ссылки на имена и / или атрибуты. Вы можете создать подкласс ast.NodeVisitor, чтобы убедиться, что в данном фрагменте кода нет таких ссылок перед вами eval:

import ast
from textwrap import dedent

class Validate(ast.NodeVisitor):
    def visit_Name(self, node):
        raise ValueError("Reference to name '%s' found in expression" % node.id)
    def visit_Attribute(self, node):
        raise ValueError("Reference to attribute '%s' found in expression" % node.attr)

Validate().visit(ast.parse(dedent(raw), '<inline>', 'eval'))
eval(raw)
0
ответ дан blhsing 22 January 2019 в 19:18
поделиться

Интересный вопрос. Я не уверен, есть ли здесь какое-либо решение для ast.literal_eval, но я предлагаю дешевый / безопасный способ:

def my_literal_eval(s):
    ast.literal_eval(s)
    return eval(s)
0
ответ дан wim 22 January 2019 в 19:18
поделиться

Ни ast.literal_eval, ни ast.parse не предоставляют возможность устанавливать флаги компилятора. Вы можете передать соответствующие флаги в compile, чтобы проанализировать строку с активированным unicode_literals, а затем запустить ast.literal_eval на полученном узле:

import ast

# Not a future statement. This imports the __future__ module, and has no special
# effects beyond that.
import __future__

unparsed = '"blah"'
parsed = compile(unparsed,
                 '<string>',
                 'eval',
                 ast.PyCF_ONLY_AST | __future__.unicode_literals.compiler_flag)
value = ast.literal_eval(parsed)
0
ответ дан user2357112 22 January 2019 в 19:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: