Джедаи - автозаполнение Python (подсказки) не показывает методы или предложения

В настоящее время я работаю над Sublime Text 3 с использованием автозаполнения Jedi - Python, и, если быть точным, он работает с большинством основных вещей. Однако я использую его, как в этом случае, с BeautifulSoup4

Основная проблема заключается в том, что при использовании методов с несколькими точками (. ) для файла не отображаются правильные завершения. и завершитель должен полагаться на то, что сначала увидит его, как метод .find_all, тогда он предложит его (однако, похоже, это автодополнение из самого Sublime Text 3).

Что будет в следующем случае

import requests
from bs4 import BeautifulSoup as Soup // works ok, shows all suggestions

request = requests.get('http://example.com')    
soup = Soup(request.text, 'lxml')


main = soup.find('body') // shows find method 
//However, No available completions in the next case
second_lookup = main.find('div') // doesn't show any autocompletions/hints when starting w/ .fi..

То же самое и с любыми другими «более глубокими» методами автозаполнения. До сих пор я пытался настроить все параметры в файле Jedi..settings. Это не помогло, и я пробовал использовать Anaconda, так как в нем есть несколько дополнительных инструментов, в том числе Jedi.

Кажется, это характерно для некоторых библиотек, например, numpy и bs4.

Примечание:

Это не специфично для Sublime Text 3. То же самое и для Atom и аналогичных IDE.


person elvirmuslic    schedule 28.10.2019    source источник
comment
Что-нибудь отображается после того, как вы наберете . после main?   -  person Dinko Pehar    schedule 28.10.2019
comment
Нет, завершений не видно. Предполагалось показать методы класса (от bs4)   -  person elvirmuslic    schedule 29.10.2019
comment
Я проверю это позже   -  person Dinko Pehar    schedule 29.10.2019
comment
Спасибо, надеюсь, кто-то (например, вы) сможет больше прояснить проблему и, по крайней мере, понять, в чем проблема. Как и пинпоинт, ядро ​​джедаев делает это неправильно.   -  person elvirmuslic    schedule 29.10.2019
comment
Проблема в основном в том, что код в bs4.element.Tag._find_all (что и делает Soup.find) настолько трудно вывести, что джедаи его просто не понимают. Когда я читаю код, я даже не совсем уверен, какие могут быть типы возврата. Итак, как бы джедаи могли понять ... В любом случае: решением было бы дать методу find аннотацию, чтобы показать, какие типы он возвращает. В настоящее время очень непонятно, что там возвращают.   -  person Dave Halter    schedule 08.11.2019


Ответы (1)


Python - динамический язык. Аргументы функции или метода полностью зависят от спецификации типа строками документации. То же самое и для возвращаемого типа.

Например, это docstring (или документация) get функции модуля requests:

def get(url, params=None, **kwargs):
    r"""Sends a GET request.

    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param \*\*kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    kwargs.setdefault('allow_redirects', True)
    return request('get', url, params=params, **kwargs)

Тип возврата указывается в определении функции. Вы также можете указать тип аргументов для функций.

Однако метод find класса Soup записывается так:

def find(self, name=None, attrs={}, recursive=True, text=None,
         **kwargs):
    """Return only the first child of this Tag matching the given
    criteria."""
    r = None
    l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
    if l:
        r = l[0]
    return r

Редакторы могут искать find метод класса Soup. Но они не знают, какой тип объекта возвращает этот метод.


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

import requests
from bs4 import Tag
from bs4 import BeautifulSoup as Soup

request = requests.get('http://example.com')

soup = Soup(request.text, 'lxml')

main: Tag  = soup.find('body')

# Auto completion works.
second_lookup = main.find('div')

Или вы можете добавить :rtype: Tag в find строку документа. Я знаю, что он возвращает объект Tag, поскольку оба type(main) или type(second_lookup) возвращают <class 'bs4.element.Tag'>.

Ссылки, которые я предоставил, достаточно, чтобы вы узнали о статической типизации в Python и идеально документировали свой код. Надеюсь это поможет.

person Dinko Pehar    schedule 29.10.2019
comment
Спасибо, это была очень полезная информация. Надеюсь, мы сможем придумать что-то другое, кроме этого решения, поскольку оно не очень удобно и НЕ будет работать для обычного пользователя. Поэтому я хотел бы найти более удобное решение для масс. Я очень ценю, что вы нашли время написать этот пост, и примете его как решение, если не появится другого ответа. - person elvirmuslic; 29.10.2019
comment
Без проблем. Я согласен с вами, что ответ - это обходной путь. Но это проблема динамических языков, например javascript (или некоторых, если это библиотека или фреймворк). Потому что все динамично. Однако сегодня Typescript очень популярен. И эти аннотации типов имеют большое значение для intellisense. - person Dinko Pehar; 29.10.2019
comment
Можно ли поместить это: TAG в библиотеку beautifulsoup, чтобы она работала оттуда? Затем после предлагать коммит и слиться с ними? - person elvirmuslic; 31.10.2019
comment
Вы можете. Но они размещены на ланчбэде. launchpad.net/beautifulsoup. Может, там можно сообщить об ошибке? - person Dinko Pehar; 31.10.2019