Декоратор, сохраняющий подпись Python, не возвращает func - PullRequest
0 голосов
/ 30 августа 2018

У меня есть проект, который автоматически документируется Sphinx и ReadTheDocs. Некоторые методы используют декоратор, который я определил. При использовании этого декоратора автоматическая документация отображает общую подпись типа my_func(*args, **kwargs)

Чтобы сохранить подпись, я использую модуль decorator. Я не хочу, чтобы мой проект зависел от этого модуля, я использую его только для генерации документации, которая выполняется ReadTheDocs.org. Моя документация require.txt включает в себя декораторы.

Итак, моя проблема заключается в следующем. Декоратор должен вернуть функцию, когда я использую @decorator, мой декоратор, похоже, ожидает, что я верну результат функции. Это различие в поведении не позволяет мне сделать мой проект независимым от модуля декоратора, но при этом сохранить подпись для Sphinx.

Вот мой CDE, может быть, яснее будет просто посмотреть на него.

try:
    from decorator import decorator
except ImportError:
    def decorator(f):
        return f

@decorator
def my_decorator(func, *args, **kwargs):
    def decorated(*args, **kwargs):
        return func(*args, **kwargs)

    decorated._some_property = 'foo'

    return decorated

@my_decorator
def some_func(self, a, b):
    return 123

Приведенный выше код работает, когда у меня не установлен пакет decorator и Sphinx может прочитать подпись some_func. Когда у меня установлен пакет decorator, мой код терпит неудачу: some_func возвращает функцию вместо 123.

Теперь я могу изменить свой декоратор на return func(*args, **kwargs), но это будет означать, что модуль decorator теперь является требованием для моего проекта.

Я тоже пробовал это:

_DECORATOR_MODULE_LOADED = False
try:
    from decorator import decorator
    _DECORATOR_MODULE_LOADED = True
except ImportError:
    def decorator(f):
        return f
#...
#...
if _DECORATOR_MODULE_LOADED:
    return decorated(*args, **kwargs)
else:
    return decorated

Что работает, но теперь я не могу получить доступ some_func._some_property

Что я могу сделать? Спасибо

...