Могу ли я подавить раскрытие переменных в документации Sphinx?

В моем коде у меня есть

X_DEFAULT = ['a', 'long', 'list', 'of', 'values', 'that', 'is', 'really', 'ugly', 'to', 'see', 'over', 'and', 'over', 'again', 'every', 'time', 'it', 'is', 'referred', 'to', 'in', 'the', 'documentation']

и позже

def some_function(..., x=X_DEFAULT, ...):

так что в моей документации Sphinx, используя (например, используя .. autofunction:: и т. д.), я получаю все длинное и громоздкое значение X_DEFAULT, развернутое в подписи для some_function:

some_function(..., x=['a', 'long', 'list', 'of', 'values', 'that', 'is', 'действительно' , 'уродливый', 'к', 'видеть', 'сверх', 'и', 'снова', 'снова', 'каждый', 'время', 'это', 'есть', 'упомянутый', ' to', 'in', 'the', 'документация'], ...)

Есть ли способ подавить эту замену в сгенерированной документации, в идеале со ссылкой на определение X_DEFAULT:

some_function(..., x=X_DEFAULT, ...)


Я знаю, что могу вручную переопределить сигнатуру для каждой функции и метода, которые я явно перечисляю в качестве аргументов директив документации Sphinx, но это не моя цель. Я также знаю, что могу использовать autodoc_docstring_signature и первую строку строки документации, но это приведет к созданию плохих строк документации, действительно предназначенных для случаев, когда самоанализ терпит неудачу (например, C). Я подозреваю, что могу кое-что сделать в autodoc-process-signature. это может быть адекватно (но не идеально), хотя я не уверен, как действовать дальше.


person orome    schedule 22.01.2014    source источник
comment
@delnan: я не уверен, как использовать это для того, что я хочу. Я добавил ответ, который является началом, но с радостью приму лучший ответ или тот, который исправит мои недостатки.   -  person orome    schedule 23.01.2014


Ответы (1)


Один подход, который, например, «отменяет» замену всех значений, которые были определены на уровне модуля как «общедоступные константы» (распознаваемые именами, состоящими из заглавных букв без начального подчеркивания), для которых можно найти уникальное имя в модуль, в котором он был определен:

def pretty_signature(app, what, name, obj, options, signature, return_annotation):
    if what not in ('function', 'method', 'class'):
        return

    if signature is None:
        return

    import inspect
    mod = inspect.getmodule(obj)

    new_sig = signature
    # Get all-caps names with no leading underscore
    global_names = [name for name in dir(mod) if name.isupper() if name[0] != '_']
    # Get only names of variables with distinct values
    names_to_replace = [name for name in global_names
                        if [mod.__dict__[n] for n in global_names].count(mod.__dict__[name]) == 1]
    # Substitute name for value in signature, including quotes in a string value
    for var_name in names_to_replace:
        var_value = mod.__dict__[var_name]
        value_string = str(var_value) if type(var_value) is not str else "'{0}'".format(var_value)
        new_sig = new_sig.replace(value_string, var_name)

    return new_sig, return_annotation

def setup(app):
    app.connect('autodoc-process-signature', pretty_signature)

Альтернативой является просто взять строку документации непосредственно из источника:

import inspect
import re

def pretty_signature(app, what, name, obj, options, signature, return_annotation):
    """Prevent substitution of values for names in signatures by preserving source text."""
    if what not in ('function', 'method', 'class') or signature is None:
        return

    new_sig = signature
    if inspect.isfunction(obj) or inspect.isclass(obj) or inspect.ismethod(obj):
        sig_obj = obj if not inspect.isclass(obj) else obj.__init__
        sig_re = '\((self|cls)?,?\s*(.*?)\)\:'
        new_sig = ' '.join(re.search(sig_re, inspect.getsource(sig_obj), re.S).group(2).replace('\n', '').split())
        new_sig = '(' + new_sig + ')'

    return new_sig, return_annotation
person orome    schedule 22.01.2014
comment
Есть несколько проблем с первой версией, которые, как мне кажется, решает вторая: (1) она беспорядочна и, вероятно, неправильно использует такие вещи, как __dict__, это (2) я не уверен, что действительно правильно и надежно проверяю, в какой подписи определен (и для которого он задокументирован), (3) он не обрабатывает подстановку между модулями (например, значения по умолчанию для именованного параметра, который определен в модуле, отличном от того, в котором определена сигнатура), он (4) не реализует ссылку Sphinx на определение константы и (5) не обрабатывает константы уровня класса. - person orome; 29.01.2014
comment
Второй, вероятно, имеет (а) проблемы с RegEx, вероятно, натыкается на исходный код, который включает комментарии или странные символы, и (в) может пропустить некоторые вещи, о которых я не знаю. - person orome; 29.01.2014
comment
Я бы принял в качестве ответа все, что решает эти проблемы с любым подходом. - person orome; 29.01.2014