Как я могу документировать ключи словаря для аргумента функции? - PullRequest
2 голосов
/ 02 апреля 2020

Я пытаюсь выяснить, как я могу предоставить подсказки типов для аргумента словаря, передаваемого в функцию, без использования Dict[str, str], поскольку это не обеспечивает, какими будут ключи.

До сих пор я пробовал два подхода, один с использованием typing_extensions, чтобы у меня была совместимость с 3,6, а также с pydantic, но я не могу показать хиты, чтобы показать.

Рассмотрим пример этого кода:

from typing_extensions import TypedDict
from pydantic import BaseModel

class Some(TypedDict):
    """keya is some key"""
    keya: str
    """another_key is another key"""
    another_key: str

def some(a: Some) -> None:
    print(a.get('keya'))
    return None


some({'keya': 'key', 'another_key': 'nonething'})

enter image description here

Как и ожидалось, подсказки типа для функции some показывают тип Some, но не его ключи.

То, что я пытаюсь сделать sh, - это две вещи.

  • Предоставляет подсказки клавиш, когда аргумент функции является диктом (наиболее важным)
  • Создание документации с помощью sphinx, чтобы ключи отражались в документации.

Редактировать

Как указано в комментариях, я могу до sh выполнить это до **kwargs до некоторой степени, но это не является намерением. Установка **kwargs также не дает мне подсказок типа.

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Я думаю, что в этом случае, возможно, было бы лучше подать запрос функции / отправить запрос на извлечение вашему редактору, улучшив качество подсказок его типа. Аналогично, с помощью sphinx вы можете отправить запрос на извлечение, который гарантирует, что документы либо правильно ссылаются на определение Some, либо включают более подробное описание в саму сигнатуру функции.

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

Вы также можете получить лучшие результаты, если вы используете "конструктор" Some вместо передачи в dict литерал. По крайней мере, для меня это дает мне полные подсказки клавиш для Some при использовании PyCharm. Не уверен, что так будет и с вашим редактором:

some(Some(keya='key', another_key='nonething'))

Обратите внимание, что выполнение Some(...) на самом деле просто возвращает обычный старый обычный dict во время выполнения, поэтому это не должно привести к каким-либо различиям. в поведении.

Также стоит попробовать:

x: Some = {
    "keya": "key",
    "another_key": "nonething",
}
some(x)

... чтобы увидеть, может ли ваш редактор дать лучшие подсказки с этой формой.

0 голосов
/ 03 апреля 2020

Я несколько сузился до возможного решения, используя следующий код. Он удовлетворяет большинству требований:

  • проверки типа mypy
  • показывает ключи
  • документация также показывает ключи и типы
  • Основная полость к это решение заключается в том, что mypy считает значение необязательным из-за значения по умолчанию, поэтому решение не совсем завершено.

Используя функцию validate_items, я могу проверить наличие значений. См. Комментарии к фрагменту кода и предложения.

from typing_extensions import TypedDict
from typing import Union

class Some(TypedDict):
    keya: str
    another_key: str

def validate_items(v: dict) -> None:
    for key, value in v.items():
        assert isinstance(value,str), '{} is required'.format(key)
        # Would love to pull the type of a key from the Some class here or
        # would love to put the validation in the Some class itself


def some(a: Some={'keya': '', 'another_key': ''}) -> None:
    """[summary]

    Args:
        a (Some, optional): [description]. Defaults to {'keya': '', 'another_key': ''}.

    Returns:
        [type]: [description]
    """    
    validate_items(dict(a))
    print(a.get('keya'))
    return None

enter image description here

На снимке экрана видно, что mypy жалуется на None ожидаемое значение, и во всплывающей справке мы также видим, что ключи, необходимые в словаре, передаются вместе с типом, который ему задан.

Решение выглядит довольно хакерским, и был бы признателен за любые исправления, чтобы сделать его более pythoni c.

...