Как сделать декоратор прозрачным для отладчика - PullRequest
0 голосов
/ 07 сентября 2018

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

Я реализовал декоратор как класс (см. https://github.com/mapa17/configfy/blob/master/configfy/decorator.py)

и пользовательская функция заключена в следующий код библиотеки:

def __call__(self, *args, **kwargs):
    if self.needs_wrapping:
        self.needs_wrapping = False
        self.func = args[0]
        functools.update_wrapper(self, self.func)
        self.kwargs = self.__get_kw_args(self.func)

        # If config file is specified in decorator, new kwargs can be precalculated!
        if self.config is not None:
            self.new_kwargs = self._get_new_kwargs()

        return self

    # Use precalculated kwargs if available
    if self.new_kwargs is None:
        new_kwargs = self._get_new_kwargs()
    else:
        new_kwargs = self.new_kwargs

    # Overwrite them with any passed arguments; passed arguments have priority!
    new_kwargs.update(kwargs)

    # Call target (aka user) function with altered kwargs
    return self.func(*args, **new_kwargs)

Так можно ли как-нибудь пропустить этот код библиотеки при отладке?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Как уже упоминалось @ bruno-desthuilliers, декоратор - это обертка вокруг пользовательской функции, и ее невозможно каким-либо образом удалить.

Что можно сделать, чтобы заставить отладчик пропустить код модуля декоратора, используя опцию skip , см.

Поскольку я заинтересован в использовании pudb для отладки, я создал pull-запрос, включив аналогичную функцию для pdb , см.

для pdb

import pdb
from configfy import configfy as cfy    

@cfy
def fuu(kw_me=42):
    print(kw_me)

if __name__ == '__main__':
    pdb.Pdb(skip=['configfy.*']).set_trace()
    fuu()

для pudb (если запрос на получение ответа принят)

import pudb
from configfy import configfy as cfy

# Prevent pudb from stepping into the decorator library code
pudb._get_debugger(skip=['configfy.*'])


@cfy
def fuu(kw_me=42):
    print(kw_me)

if __name__ == '__main__':
    pudb.set_trace()
    fuu()
0 голосов
/ 11 сентября 2018

В декораторах нет ничего волшебного. Синтаксис @decorator является только синтаксическим сахаром, поэтому, когда вы пишете:

@decorate
def some_func(...):
   # ...

технически, что на самом деле происходит:

def some_func(...):
   # ...

some_func = decorate(some_func)

IOW, нет, нет способа «сделать декоратор прозрачным для отладчика», так как «декоратор» - это просто обычный вызываемый объект, который (обычно, но не обязательно) возвращает другой обычный обычный вызываемый элемент - фактически это просто нет такой вещи, как «декоратор», вызываемый является декоратором, если вы используете его как таковой, и все.

...