Поля MongoEngine, типизация и PyCharm

PyCharm выдает предупреждение о типе при работе со значением поля MongoEngine. Например, при работе с StringField как с str:

class ExampleDocument(Document):
    s = StringField()

doc = ExampleDocument(s='mongoengine-test')
print(doc.s.endswith('test'))

Я получаю предупреждение Неразрешенная ссылка на атрибут 'endswith' для класса StringField, если я не использую typing.cast (т.е. typing.cast(str, doc.s).endswith('test'). Код выполняется так, как предполагалось, но есть ли способ избавиться от этих предупреждений, а также получить необходимые автозаполнения для типов полей MongoEngine?


person Aleph Aleph    schedule 01.10.2017    source источник


Ответы (1)


Возможно, это не лучшее из всех мыслимых решений, но вы можете добавлять свои собственные подсказки типов непосредственно в объявления полей. Либо используя синтаксис 2.7 с комментариями (также работает в 3.x):

class ExampleDocument(Document):
    s = StringField()  # type: str

Или с 3.x:

class ExampleDocument(Document):
    s: str = StringField()

Использование определений типов в строках документа также должно работать:

class ExampleDocument(Document):
    s = StringField()
    """:type: str"""

Любой из них дает PyCharm (или Intelij с плагинами Python) необходимые подсказки о типе, который следует использовать для этих полей.

Обратите внимание, что теперь вы будете получать предупреждения при доступе к чему-либо из исходных типов полей mongoengine, потому что вы эффективно заменили тип, используемый для проверки типов. Если вы хотите, чтобы PyCharm распознавал как тип mongoengine, так и тип Python, вы можете использовать тип Union:

from typing import Union
class ExampleDocument(Document):
    s = StringField()  # type: Union[str, StringField]

Более подробную информацию об использовании типов hin в PyCharm можно найти в документации по PyCharm здесь.

person Markus    schedule 15.11.2017
comment
Спасибо, это более или менее то, что я использую. Есть ли способ объявить, что один тип расширяет другой (например, что StringField реализует все методы str)? - person Aleph Aleph; 16.11.2017
comment
Вы можете использовать Union[str, StringField] в комментарии или подсказки типа Python 3.x. Union должен быть импортирован из модуля typing. - person Markus; 17.11.2017