Как Вы превращаете неупомянутую функцию/лямбду Python в AST? 2.6

Одно слово: Knipex

7
задан Chris 23 September 2009 в 22:03
поделиться

4 ответа

Если вы получаете доступ только к функции / лямбда-выражению, у вас есть только скомпилированный байт-код python. Точный Python AST не может быть восстановлен из байт-кода, потому что в процессе компиляции происходит потеря информации. Но вы можете проанализировать байт-код и создать для этого AST. В GeniuSQL есть один такой анализатор. У меня также есть небольшое доказательство концепции, которая анализирует байт-код и создает из него элементы предложения SQLAlchemy.

Я использовал следующий процесс для анализа:

  1. Разделите код на список кодов операций с потенциальными аргументами.
  2. Найти базовые блоки в коде путем прохождения кодов операций и для каждого перехода создают границу базового блока после перехода и перед целью перехода
  3. Создайте граф потока управления из базовых блоков.
  4. Пройдите через все основные блоки с абстрактным стеком отслеживания интерпретации и назначением переменных в форме SSA.
  5. Чтобы создать выходное выражение, просто получите вычисленное возвращаемое значение SSA.

Я вставил свое доказательство концепции. и пример кода с его использованием . Это не чистый, быстро взломанный код, но вы можете его использовать, если хотите. Оставьте записку, если решите сделать из нее что-нибудь полезное.

6
ответ дан 6 December 2019 в 08:15
поделиться

You can't generate AST from compiled bytecode. You need the source code.

1
ответ дан 6 December 2019 в 08:15
поделиться

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

0
ответ дан 6 December 2019 в 08:15
поделиться

В общем, нельзя. Например, 2 + 2 - это выражение, но если вы передадите его в любую функцию или метод, переданный аргумент будет просто числом 4 , невозможно восстановить, какое выражение это было вычислено из. Исходный код функции иногда можно восстановить (хотя и не для лямбда ), но «выражение Python без кавычек» получает оценку , поэтому вы получаете только объект, являющийся значением выражения.

Какую проблему вы пытаетесь решить? Могут быть и другие жизнеспособные подходы.

Edit : tx to OP для уточнения. Невозможно сделать это для лямбда или некоторых других угловых случаев, но, как я уже упоминал, исходный код функции иногда можно восстановить ...:

import ast
import inspect

def f():
  return 23

tree = ast.parse(inspect.getsource(f))

print ast.dump(tree)

inspect. getsource вызывает IOError , если не может получить исходный код для любого объекта, который вы ему передаете. Я предлагаю вам обернуть вызов синтаксического анализа и getource во вспомогательную функцию, которая может принимать строку (и просто анализировать ее) ИЛИ функцию (и пытается на ней getource, что, возможно, дает лучшие ошибки в случае IOError ).

10
ответ дан 6 December 2019 в 08:15
поделиться
Другие вопросы по тегам:

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