Представляем getsources: получение исходного кода Python-функций.
Получает чистый и пригодный для парсинга исходный код из объектов Python-функций, включая вложенные и интерактивные определения.
На этой странице 3 раздела
Инструменты, которые анализируют или изменяют Python-код, часто получают готовый объект функции, но для работы им нужен создавший её читаемый исходный текст. Найти его не всегда просто: функция из интерактивной консоли может не иметь обычного файла, а функция внутри класса или другой функции сохраняет внешний отступ и не разбирается отдельно.
Стандартное решение — inspect.getsource(), а dill и sourceinspect поддерживают больше интерактивных окружений. Их интерфейсы и результаты различаются, поэтому инструментам, разбирающим структуру кода, приходится самим выбирать запасной способ и исправлять отступы.
getsources — небольшая Python-библиотека, которая единообразно получает такой текст и готовит его к разбору. Сначала она использует стандартный модуль inspect, при необходимости обращается к dill и умеет удалять отступ, унаследованный от окружающего кода. Релиз доступен на GitHub.
Получение и нормализация исходника
getsource(function) сначала вызывает inspect.getsource(), а после OSError переключается на dill.source.getsource(), в том числе для определений из истории обычной интерактивной консоли Python.
getclearsource(function) удаляет отступ внешнего класса или функции, сохраняя отступы внутри тела функции.
from getsources import getclearsource
class Parser:
@staticmethod
def parse(value):
return int(value)
print(getclearsource(Parser.parse))
#> def parse(value):
#> return int(value)
Полученный текст можно разобрать, не восстанавливая окружающий класс.
Библиотека работает с функциями, написанными на Python, включая методы и лямбда-функции, но не с модулями, классами, встроенными функциями и произвольными вызываемыми объектами. Лямбда-функция всё ещё может вернуться вместе с окружающей инструкцией, например handler = lambda value: value + 1.
Как выбрать инструмент восстановления исходника
Для обычного файлового кода проекту может быть достаточно textwrap.dedent(inspect.getsource(function)). inspect.getsourcelines() также возвращает номера строк и поддерживает больше видов объектов, а прямое использование dill даёт больше настроек восстановления.
sourceinspect поддерживает больше интерактивных оболочек. executing и stack-data лучше подходят для анализа frame или traceback, а cloudpickle переносит поведение между процессами вместо восстановления читаемого исходника.
В интерактивной среде библиотека делает всё возможное, но не может гарантировать результат. У динамического кода из exec или eval может не быть надёжного источника, сопоставление лямбда-функции с историей бывает неоднозначным, а файл на диске может уже не соответствовать загруженной функции. getsources восстанавливает исходный текст, а не пытается собрать его обратно из машинного представления Python.
Для чего предназначен getsources
Пакет даёт библиотекам, разбирающим структуру Python-кода, единый интерфейс для функций из модулей, вложенных областей и обычной интерактивной консоли.