НОВОСТИ

Получает чистый и пригодный для парсинга исходный код из объектов 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-кода, единый интерфейс для функций из модулей, вложенных областей и обычной интерактивной консоли.